I have implemented chat feature using sockjs-tornado and could store the messages in RethinkDB.
Could you please help me on how do I establish private channel for messaging in sockjs-tornado ? (I mean Private conversation / one to one)
Below is the on_message function in my server side code -
def on_message(self, message):
str=message
mg=str.split('#:#')
sender=1 # This is the sender user id
receiver=2 #This is the receiver user id - I need to implement session variables to have these id's so that I can use it here this way
ts=r.expr(datetime.now(r.make_timezone('00:00')))
connection = r.connect(host="192.x.x.x")
r.db("djrechat").table('events').insert({"usrs":mg[0],"msg":mg[1],"tstamp":ts,"snder":sender,"rcver":receiver}).run(connection)
log.info(message)
self.broadcast(self.participants, '{} - {}'.format(self.stamp(),message))
Currently this is broadcasting to all the clients connected. May be I should have a channel id and to send message only to the two clients which will have the same channel id, but how do I implement it or is there any better solution for this?
At client side, I have below javascript -
function connect() {
disconnect();
conn = new SockJS('http://localhost:8080/chat', ['websocket','xhr-streaming','iframe-eventsource','iframe-htmlfile','xhr-polling','iframe-xhr-polling','jsonp-polling']);
//log('Connecting.....');
conn.onopen = function() {
// log('Connected. (' + conn.protocol + ')');
log('Connected.');
};
conn.onmessage = function(e) {
log(e.data);
};
conn.onclose = function() {
log('Disconnected.');
conn = null;
};
}
Am using python 3.4 - Django 1.8.4 and Rethinkdb
My answer makes the assumption that all clients in the current solution connect to a SockJS server with a channel name that is used for broadcasts of the chat messages (or something close to this scenario). I further assume that the round-trip when a user sends a message from the client is:
There are multiple solutions to this problem. I will only outline the one I think is simplest and most robust here:
Another, slightly more complex, and inelegant solution would be to create ad hoc channels for each private pair when needed. However, how would you get
User B
to subscribe to the (newly created) private channel whenUser A
wants to chat withUser B
? One way would be to broadcast a request forUser B
to connect to that channel, but that would tell all the other clients (at the code level) about this private chat that will take place; and if any of those clients are compromised, that information can be misused for, for example, eavesdropping or crashing the private party.Additional Advice
I would also like to mention that since I wrote my sockjs - example of implementing rooms answer, I have changed my own architecture to (still) use
SockJS
in the front-end, but with RabbitMQ using the Web-STOMP plugin on the back-end. That way,The whole new solution is placed behind HAProxy which terminates HTTPS and SSL/TLS-encrypted WebSocket connections.