有没有人做过 Http, socket 混合服务器的

2017-06-26 09:38:30 +08:00
 abcbuzhiming
之前用 spring-mvc 做的 http 服务,现在需要实时推送,限于技术原因。不能使用 http2,本来打算用 websocket 的,但是发现一个问题,webscorket 在 java 下必须单独使用一个 servlet,不能和处理 http 请求的 servlet 复用,导致 session 等安全认证信息无法复用。于是就陷入僵局了,该如何改造现有这个系统?
7096 次点击
所在节点    Java
35 条回复
janxin
2017-06-26 09:42:19 +08:00
websocket 不是 http,你说的这些本来就不一定能用
nutting
2017-06-26 09:45:56 +08:00
用 spring 引入 mina 这种 socket 框架?
hncqp
2017-06-26 09:46:59 +08:00
如果用 cpp 就简单了,不过 java 应该也是可以直接用 socket 的吧?
HunterPan
2017-06-26 09:50:20 +08:00
可以用 spring-websocket
des
2017-06-26 10:04:09 +08:00
如果实在没辙何不单独再写一套专门用来推送的?
RainFinder
2017-06-26 10:10:36 +08:00
@des 什么叫专门用来推送的?
dthor
2017-06-26 10:17:06 +08:00
如果只是服务端推送的话,可以考虑 server sent event
ixiaohei
2017-06-26 10:32:59 +08:00
以前我搞过,当时选 spring 的 websocket 集成,但是不了解框架内部原理集成失败了,后面 netty 搞的 socket 长连接做的推送,用 listener 启动 netty 服务就行,另外主要 keepalive 和 tcp 粘包处理。
ixiaohei
2017-06-26 10:37:17 +08:00
注意做好 keepalive 和 tcp 粘包处理,注意区分 keepalive 时候服务器推和客户端推各自的好处,主要是清除 tcp 非意外断开的链接,忘记这个学术名词叫啥了。
abcbuzhiming
2017-06-26 10:41:07 +08:00
@des 核心问题时想复用现在的这一套用户验证机制,结果发现目前基于 session ( cookie )的验证机制没法用在新的推送上
abcbuzhiming
2017-06-26 10:43:45 +08:00
@RainFinder 以前的交换模型是纯粹的“请求——响应”,而且用用户验证机制,基于 session ( shiro )的,要推送的话,也是必须先沿着用户身份的,所以开始才考虑 websocket,希望能无痛升级,结果发现无法复用,java 实现的 websocket 有一个要求,用于处理 websocket 请求的那个 servlet 必须是独立的,并不能复用处理普通 http 请求的那个,于是就无法复用现有的用户验证体系。就僵在这里了
RainFinder
2017-06-26 10:55:38 +08:00
@dthor 看了介绍,其实也就是一种长连接吧,做了事件监听
RainFinder
2017-06-26 10:57:51 +08:00
记得当初看 websocket 是在 header 中加入了特殊字段标识 websocket 吧,其他验证信息也是可以获取的啊,你的认证信息是怎么实现的,cookie 吗
fzleee
2017-06-26 11:14:02 +08:00
可以这么做:
1. 假定 http 的服务和 websocket 的服务各有一个,运行在独立的进程甚至独立的服务器上。
2.浏览器首次建立 websocket 连接时,websocket 服务器从浏览器请求的 cookie 里面获取认证 token。
3. websocket 服务器同步或者异步将 cookie 发送给 http 服务进行认证。认证失败则断开连接。
vjnjc
2017-06-26 11:41:13 +08:00
感兴趣,貌似 socket 和 http server 没法在同一个 domain(schema://host:port)下面混用吧。
坐等高手
wucao219101
2017-06-26 11:48:00 +08:00
可以用 spring-websocket,另外 Session 是可以复用的。

具体配置:
```
<websocket:handlers>
<websocket:mapping path="/websocket/chat" handler="chatWebsocketHandle" />
<websocket:handshake-interceptors>
<bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor" />
</websocket:handshake-interceptors>
</websocket:handlers>
<bean id="yourWebsocketHandle" class="com.xxg.YourWebsocketHandle" />
```
在 YourWebsocketHandle 中再通过
```
String value = (String) webSocketSession.getAttributes().get("your-session-key");
```
可以获取 session 的值。
sagaxu
2017-06-26 12:17:29 +08:00
真有意思,我记得之前用 websocket,配置文件改改就好了啊
NUT
2017-06-26 12:21:29 +08:00
最好的是自己用 Netty 开发一个服务端,鉴权通过目前系统实现。开发工作量不小。
zander1024
2017-06-26 12:21:50 +08:00
。。。 没做过 java 的 .net 的做过一个简易的 。

java 实现的 websocket 有一个要求,用于处理 websocket 请求的那个 servlet 必须是独立的,并不能复用处理普通 http 请求的那个,于是就无法复用现有的用户验证体系。就僵在这里了

.net 里需要继承 webapi 但是貌似没有规定必须是一个独立的服务
fzleee
2017-06-26 13:10:45 +08:00
@vjnjc 这个可以做到的。比如用一个 nginx 做服务分发

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/371055

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX