How to integrate SockJS with another web framework
Asked Answered
M

3

7

As an alternative to Socket.io, there is SockJS (https://github.com/sockjs/sockjs-client), which seems to be better maintained and more stable than Socket.io.

This question is about the conceptual understanding the architecture of using SockJS with a web framework, say, for building a chat application

My current understanding is that you need the SockJS-client and a SocketJS server (in my case, I intend to use SockJS-Tornado (https://github.com/MrJoes/sockjs-tornado)) to be able to make websockets-style communication.

But how does SockJS (SockJS-client + SockJS-Tornado) tie together with a web framework that does the rest of the work (e.g. serving the page, writing/reading to/from db, etc). For instance, how would SockJS-Tornado component communicates with the web server of the framework? In particular, any direction of doing this with web2py (a python web framework) is highly appreciated.

Meissen answered 3/5, 2012 at 17:24 Comment(3)
You can use a message queue such as RabbitMQ or ZeroMQ.Ulund
@igorw, are you saying that I can use a message queue to connect SockJS-Tornado server to the web server of the framework, so that stuff received by SockJS-Tornado can be shared with the framework? Could you please elaborate? Thanks.Meissen
By the way, there is also autobahn.wsOlimpia
D
4

You're right, for SockJS you need a sockjs-capable server and a in-browser javascript client library.

There are generally two integration patterns, let's say you want to use sockjs-tornado:

  1. You may have all your site served from Tornado. With that, hook sockjs-tornado to some path, for example 'http://mysite.com/sockjs'. In this scenario both your website and sockjs will be served from mysite.com domain.
  2. You may keep your site in whatever language/framework it's written and add sockjs-serveras another compontent, under a different domain, like. 'http://sockjs.mysite.com/sockjs'.

Additionally, you may use any variation of this - for example: have two servers internally but expose them as one domain by using a smart loadblancer (like haproxy).

Deme answered 8/5, 2012 at 10:50 Comment(3)
thanks for the suggestions. I would like to know more about the second options you've proposed. Particularly, how to interface SockJS-Tornado with the web server that is used by the framework. For example, what is the workflow of a request from the browser to the server-side (consists of a SockJS-Tornado and a web server of the framework) and back? Thanks.Meissen
Keep two separate servers. One - your old app. New - sockjs-tornado. Use HAProxy for routing if you want to expose it as a single domain, or just use two separate domains. If you need communication between sockjs and your app - use Redis Pub/sub, RabbitMQ or zeromq to exchange messages between the two.Deme
hi @Marek. how do i exchange messages between the app and the sockjs where i should only have 2 separate servers? my current setup is that i have to run a third one.. the zmq server script where 4 sockets are bound. 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.PUSHWaterless
S
1

If you're using web2py as a framework you could look a comet_messaging.py in gluon/contrib. It provides a function (comet_send) for getting messages from web2py app out to your websocket clients. It is based on tornado (w/o SockJS support) but the DistributeHandler can subclass a SockJS connection to provide fallback transport support. In this approach your clients send messages via typical GET or POST HTTP requests which are handled by web2py controllers (or other framework) and receive messages from the web2py controllers calling comet_messaging.comet_send() which sends a post request to the tornado instance which then blasts it out to its list of listeners.

The modified lines in comet_messaging look like (Notice open becomes 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'   

and

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

Notice I had to remove the regex group in the DistributeHandler URLSpec because sockJS-tornado was choking on it. Still trying to figure out how get parameters from the path to the on_open handler.

Structuralism answered 29/5, 2012 at 0:9 Comment(0)
O
0

This provides a full answer on how to integrate SockJS into Django: https://mcmap.net/q/356432/-python-socket-io-client-for-sending-broadcast-messages-to-tornadio2-server

Basically you need:

  • Tornado + SockJS-Tornado
  • Redis + Brukva

I use this configuration in my own project and it works pretty well.

Or: You try the autobahn way: http://autobahn.ws/ (i didn't try it out yet)

Olimpia answered 7/2, 2013 at 8:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.