有没有人做过 Http, socket 混合服务器的 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
abcbuzhiming
V2EX    Java

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

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

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

    .net 里需要继承 webapi 但是貌似没有规定必须是一个独立的服务
    fzleee
        20
    fzleee  
       2017-06-26 13:10:45 +08:00
    @vjnjc 这个可以做到的。比如用一个 nginx 做服务分发
    3dwelcome
        21
    3dwelcome  
       2017-06-26 13:17:31 +08:00
    我做过,但不是用 java。判断如果 socket 开始四个字节是"GET "或"POST",就走 http 服务器。如果不是,那么就走正常的 socket 二进制协议。
    liuxu
        22
    liuxu  
       2017-06-26 13:31:16 +08:00
    你可以用 http server + workerman
    如果要处理 session 同步问题,可以做一个内网用的接口给 workerman 查询

    详细的你可以加他们官方群,群主以前也是 V2EX 玩的,技术厉害而且对新人的问题会很耐心的解答
    QQ2171775959
        23
    QQ2171775959  
       2017-06-26 13:54:33 +08:00
    用独立的服务器来做,性能比较能够满足的。
    qieqie
        24
    qieqie  
       2017-06-26 15:13:54 +08:00
    websocket 就是为了直接复用 web infrastructure 搞出来的,
    没道理不能复用,要不然和直接用 TCP 有什么区别
    yuchting
        25
    yuchting  
       2017-06-26 17:40:54 +08:00
    我知道你们都是标准前后端的。
    我歪个楼,我用的 Java + Netty 直接写底层 socket+http 协议,直接就混了。。。
    z5864703
        26
    z5864703  
       2017-06-26 17:44:21 +08:00
    直接监听一个端口实现 websocket 和 http 服务,根据请求内容格式分发到对应业务逻辑,是可以实现的
    notreami
        27
    notreami  
       2017-06-26 19:31:19 +08:00
    为什么要用 session,而不是自行弄一个 token ?
    abcbuzhiming
        28
    abcbuzhiming  
    OP
       2017-06-26 21:32:51 +08:00
    @notreami 因为已有的代码都是基于 session 的,搞个新的,你得把之前的代码全改了
    azh7138m
        29
    azh7138m  
       2017-06-26 22:25:17 +08:00 via Android
    @fzleee schema 不一样唉,一个 ws 一个是 http
    hsmocc
        30
    hsmocc  
       2017-06-27 00:38:53 +08:00 via iPhone
    没搞过 websocket,我也想知道权限如何控制的。搜了一下,ws 的 session 是可以关联页面中 httpsession 的,它们关联的时机是在 ws 握手的时候,因为 ws 的握手是通过 http 完成的。所以我感觉权限控制可以在 ws 握手时候,如果没有权限握手就失败。
    cctrv
        31
    cctrv  
       2017-06-27 00:42:51 +08:00 via Android
    socket.io
    正在使用,java 支持 https,不用 http2
    raofeng
        32
    raofeng  
       2017-06-27 11:29:42 +08:00
    我们有个项目是这样搞的。网站用 Rails 4 + socket.io.js,然后 websocket 服务器用的 nodejs+socket.io+socket.io-emitter,session 是存在 redis 里边的。
    在前端 js 里边连接 websocket 服务器的时候会把 session_id 传过去,然后 nodejs 这边就能读取到 session 的数据。
    网站需要推送的时候用一个 Ruby Gem 包 emit 一下,就实现了推送。
    colincat
        33
    colincat  
       2017-06-27 17:35:43 +08:00 via iPhone
    可以复用,以前搞过,不过当时是基于 tomcat7 做的,session 也可以复用的
    abcbuzhiming
        34
    abcbuzhiming  
    OP
       2017-06-27 23:14:58 +08:00
    @colincat 我遇到个新问题,你们当时在 tomcat 下做 websocket,是如何解决服务端超时检测这个问题的,即一段时间没有收到来自客户端的数据就断开。这个在别的 socket 实现下很简单的功能在 tomcat 下好难啊,放狗了两天,没找到肯定的答案
    colincat
        35
    colincat  
       2017-06-28 11:09:18 +08:00 via iPhone
    @abcbuzhiming 我们是自己做心跳啊,就可以判断超时
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5173 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 38ms UTC 07:44 PVG 15:44 LAX 23:44 JFK 02:44
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86