如何将SockJS集成到另一个Web框架中

7
作为 Socket.io 的替代方案,有 SockJS(https://github.com/sockjs/sockjs-client),它似乎比 Socket.io 更好地维护和更加稳定。
这个问题是关于使用一个 Web 框架与 SockJS 架构概念的理解,例如,用于构建聊天应用程序。
我目前的理解是,你需要 SockJS 客户端和一个 SocketJS 服务器(在我的情况下,我打算使用 SockJS-Tornado (https://github.com/MrJoes/sockjs-tornado))才能进行类似 WebSocket 的通信。
但是,SockJS(SockJS-客户端 + SockJS-Tornado)如何与完成其余工作的 Web 框架(例如,提供页面、读取/写入数据库等)结合使用呢?例如,SockJS-Tornado 组件如何与框架的 Web 服务器通信?特别是,任何使用 web2py(一个 Python Web 框架)实现此功能的指导都将受到高度赞赏。

你可以使用消息队列,例如RabbitMQ或ZeroMQ。 - igorw
@igorw,你是在说我可以使用消息队列将SockJS-Tornado服务器连接到框架的Web服务器,以便SockJS-Tornado接收的内容可以与框架共享吗?你能详细解释一下吗?谢谢。 - MLister
顺便说一下,还有http://autobahn.ws/。 - Alp
3个回答

4

你说得对,对于SockJS,你需要一个支持SockJS的服务器和一个浏览器内的JavaScript客户端库。

通常有两种集成模式,比如你想使用SockJS-Tornado:

  1. 你可以将所有网站都从Tornado提供。在这种情况下,将sockjs-tornado钩子到某个路径上,例如“http://mysite.com/sockjs”。在这种情况下,您的网站和sockjs都将从mysite.com域提供服务。
  2. 您可以保留您的站点以任何语言/框架编写,并添加sockjs-server作为另一个组件,在不同的域下,如“http://sockjs.mysite.com/sockjs”。

此外,您可以使用任何变体 - 例如:通过使用智能负载均衡器(如haproxy)在内部拥有两个服务器,但将它们公开为一个域。


1
感谢您的建议。我想了解更多关于您提出的第二个选项的内容。特别是,如何将SockJS-Tornado与框架使用的Web服务器进行接口化。例如,从浏览器到服务器端(由SockJS-Tornado和框架的Web服务器组成)的请求的工作流程是什么,以及如何返回?谢谢。 - MLister
2
保留两个独立的服务器。一个是旧应用程序,另一个是sockjs-tornado。如果您想将其公开为单个域,请使用HAProxy进行路由,或者只需使用两个单独的域。如果您需要在sockjs和应用程序之间进行通信,请使用Redis Pub/sub、RabbitMQ或zeromq来交换两者之间的消息。 - Marek
嗨@Marek。我该如何在应用程序和sockjs之间交换消息,而我只需要两个独立的服务器?我的当前设置是必须运行第三个脚本..即zmq服务器脚本,其中绑定了4个套接字。receiver_from_server.bind("tcp://*:5561") # zmq.PULL forwarder_to_server.bind("tcp://*:5562") # zmq.PUSH receiver_from_websocket.bind("tcp://*:5563") # zmq.PULL forwarder_to_websocket.bind("tcp://*:5564") # zmq.PUSH - bonbon.langes

1
如果您正在使用web2py作为框架,可以查看gluon/contrib中的comet_messaging.py。它提供了一个函数(comet_send)用于将消息从web2py应用程序发送到您的websocket客户端。它基于tornado(不支持SockJS),但DistributeHandler可以子类化SockJS连接以提供回退传输支持。在这种方法中,您的客户端通过典型的GET或POST HTTP请求发送消息,这些请求由web2py控制器(或其他框架)处理,并通过调用comet_messaging.comet_send()从web2py控制器接收消息,该函数会向tornado实例发送一个post请求,然后将其发送到其侦听器列表。
comet_messaging中修改的行如下(注意open变成了on_open):
class DistributeHandler(sockjs.tornado.SockJSConnection):
    def on_open(self, r):
    group,token,name = [None, None, None]
    self.group = group or 'default'
    self.token = token or 'none'
    self.name = name or 'anonymous'   

并且

urls=[
    (r'/', PostHandler),
    (r'/token', TokenHandler),
    (r'/realtime', DistributeHandler)]

注意,我不得不从DistributeHandler URLSpec中删除正则表达式组,因为sockJS-tornado无法处理它。仍在努力弄清楚如何从路径获取参数并传递给on_open处理程序。


0

这提供了如何将SockJS集成到Django的完整答案:https://dev59.com/gmgu5IYBdhLWcg3w9br_#10950702

基本上你需要:

  • Tornado + SockJS-Tornado
  • Redis + Brukva

我在自己的项目中使用这个配置,它运行得非常好。

或者:你可以尝试autobahn的方式:http://autobahn.ws/(我还没有尝试过)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接