之前用 spring-mvc 做的 http 服务,现在需要实时推送,限于技术原因。不能使用 http2,本来打算用 websocket 的,但是发现一个问题,webscorket 在 java 下必须单独使用一个 servlet,不能和处理 http 请求的 servlet 复用,导致 session 等安全认证信息无法复用。于是就陷入僵局了,该如何改造现有这个系统?
|
janxinJun 26, 2017 via iPhone
1
websocket 不是 http,你说的这些本来就不一定能用
|
|
nuttingJun 26, 2017 via Android
2
用 spring 引入 mina 这种 socket 框架?
|
|
hncqpJun 26, 2017
3
如果用 cpp 就简单了,不过 java 应该也是可以直接用 socket 的吧?
|
|
HunterPanJun 26, 2017
4
可以用 spring-websocket
|
|
desJun 26, 2017 via Android
5
如果实在没辙何不单独再写一套专门用来推送的?
|
|
RainFinderJun 26, 2017
6
@des 什么叫专门用来推送的?
|
|
dthorJun 26, 2017
7
如果只是服务端推送的话,可以考虑 server sent event
|
|
ixiaoheiJun 26, 2017
8
以前我搞过,当时选 spring 的 websocket 集成,但是不了解框架内部原理集成失败了,后面 netty 搞的 socket 长连接做的推送,用 listener 启动 netty 服务就行,另外主要 keepalive 和 tcp 粘包处理。
|
|
ixiaoheiJun 26, 2017
9
注意做好 keepalive 和 tcp 粘包处理,注意区分 keepalive 时候服务器推和客户端推各自的好处,主要是清除 tcp 非意外断开的链接,忘记这个学术名词叫啥了。
|
|
10
@des 核心问题时想复用现在的这一套用户验证机制,结果发现目前基于 session ( cookie )的验证机制没法用在新的推送上
|
|
11
@RainFinder 以前的交换模型是纯粹的“请求——响应”,而且用用户验证机制,基于 session ( shiro )的,要推送的话,也是必须先沿着用户身份的,所以开始才考虑 websocket,希望能无痛升级,结果发现无法复用,java 实现的 websocket 有一个要求,用于处理 websocket 请求的那个 servlet 必须是独立的,并不能复用处理普通 http 请求的那个,于是就无法复用现有的用户验证体系。就僵在这里了
|
|
RainFinderJun 26, 2017
12
@dthor 看了介绍,其实也就是一种长连接吧,做了事件监听
|
|
RainFinderJun 26, 2017
13
记得当初看 websocket 是在 header 中加入了特殊字段标识 websocket 吧,其他验证信息也是可以获取的啊,你的认证信息是怎么实现的,cookie 吗
|
|
fzleeeJun 26, 2017
14
可以这么做:
1. 假定 http 的服务和 websocket 的服务各有一个,运行在独立的进程甚至独立的服务器上。 2.浏览器首次建立 websocket 连接时,websocket 服务器从浏览器请求的 cookie 里面获取认证 token。 3. websocket 服务器同步或者异步将 cookie 发送给 http 服务进行认证。认证失败则断开连接。 |
|
vjnjcJun 26, 2017
15
感兴趣,貌似 socket 和 http server 没法在同一个 domain(schema://host:port)下面混用吧。
坐等高手 |
|
wucao219101Jun 26, 2017
16
可以用 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 的值。 |
|
sagaxuJun 26, 2017
17
真有意思,我记得之前用 websocket,配置文件改改就好了啊
|
|
NUTJun 26, 2017 via iPhone
18
最好的是自己用 Netty 开发一个服务端,鉴权通过目前系统实现。开发工作量不小。
|
|
zander1024Jun 26, 2017
19
。。。 没做过 java 的 .net 的做过一个简易的 。
java 实现的 websocket 有一个要求,用于处理 websocket 请求的那个 servlet 必须是独立的,并不能复用处理普通 http 请求的那个,于是就无法复用现有的用户验证体系。就僵在这里了 .net 里需要继承 webapi 但是貌似没有规定必须是一个独立的服务 |
|
3dwelcomeJun 26, 2017
21
我做过,但不是用 java。判断如果 socket 开始四个字节是"GET "或"POST",就走 http 服务器。如果不是,那么就走正常的 socket 二进制协议。
|
|
liuxuJun 26, 2017
22
你可以用 http server + workerman
如果要处理 session 同步问题,可以做一个内网用的接口给 workerman 查询 详细的你可以加他们官方群,群主以前也是 V2EX 玩的,技术厉害而且对新人的问题会很耐心的解答 |
|
QQ2171775959Jun 26, 2017
23
用独立的服务器来做,性能比较能够满足的。
|
|
qieqieJun 26, 2017
24
websocket 就是为了直接复用 web infrastructure 搞出来的,
没道理不能复用,要不然和直接用 TCP 有什么区别 |
|
yuchtingJun 26, 2017
25
我知道你们都是标准前后端的。
我歪个楼,我用的 Java + Netty 直接写底层 socket+http 协议,直接就混了。。。 |
|
z5864703Jun 26, 2017
26
直接监听一个端口实现 websocket 和 http 服务,根据请求内容格式分发到对应业务逻辑,是可以实现的
|
|
notreamiJun 26, 2017
27
为什么要用 session,而不是自行弄一个 token ?
|
|
28
@notreami 因为已有的代码都是基于 session 的,搞个新的,你得把之前的代码全改了
|
|
hsmoccJun 27, 2017 via iPhone
30
没搞过 websocket,我也想知道权限如何控制的。搜了一下,ws 的 session 是可以关联页面中 httpsession 的,它们关联的时机是在 ws 握手的时候,因为 ws 的握手是通过 http 完成的。所以我感觉权限控制可以在 ws 握手时候,如果没有权限握手就失败。
|
|
raofengJun 27, 2017
32
|
|
colincatJun 27, 2017 via iPhone
33
可以复用,以前搞过,不过当时是基于 tomcat7 做的,session 也可以复用的
|
|
34
@colincat 我遇到个新问题,你们当时在 tomcat 下做 websocket,是如何解决服务端超时检测这个问题的,即一段时间没有收到来自客户端的数据就断开。这个在别的 socket 实现下很简单的功能在 tomcat 下好难啊,放狗了两天,没找到肯定的答案
|
|
colincatJun 28, 2017 via iPhone
35
@abcbuzhiming 我们是自己做心跳啊,就可以判断超时
|