In the tornado websocket chat example, participants are stored in the set (link) , it is convenient in the case of a single server. But if run multiple instances of the application and nginx as a load balancer, how in this case, better to store the participants?
You may consider using the pubsub feature of Redis.
(link)
Edit :
When your clients log on to your chatroom, they can subscribe to a channel, say chatroom. It does not matter which tornado instances they are using.
Using this module you can keep asynchronously listening to the channel.
If another client sends a message to your chatroom (that is publish a message to the channel chatroom), all tornado instances will automatically sends the messages to those who subscribed to the channel. Then you can send the message via websocket.
You can take a look at this demo for the example.
Related
I'm trying to find out if it is possible to have two paho.mqtt clients (https://eclipse.org/paho/clients/python/docs/) subscribing to the same server. Both clients and server are running on the same host. My aim is to have two clients subscribing with different credentials to the same server (which in my case is rabbitmq with mqtt plugin) so I can sort my payloads by vhosts (not by topic since I don't have control over topics).
My observation at the moment is that the clients just keep reconnecting which would suggest I'm either doing something wrong or that there can be only one client connected to the MQTT server at a time...
So here is the question - was you able to run more than one client subscribed to the same server where all clients and server were running locally?
Edit:
It seems RabbitMQ with MQTT plugin allows to achieve this functionality. The one could configure two users to have access to separate vhosts and just by doing this payloads get segregated. My scenario was to configure two clients so I could distinguish who had sent which payload, and localy I could spawn mirror clients to consume payload of related users.
Many thanks to #hardillb who helped with this question and with related question.
Each client must have a unique client id, the broker will kick off the oldest client when a new one connects with the same client id. Other than that you can run as many clients as you want connecting from anywhere that can reach the broker
Suppose that there is one redis-client which is subscribing to channel c1 and another redis-client publishes "data" to channel c1.
At this point, does the data published is pending in a redis-server by when the client subscribing to "c1" get the data(by calling pubsub.listen() or pubsub.get_message()) or go directly to the client subscribing to the channel c1 through a redis-server?
In other words, When a redis-client call pubsub.getMessage() or pubsub.listen(), does redis-client send a request to redis-server to get data or just get data from the local socket buffer?
When I read some documents it is saying that pubsub.get_message() use select module for a socket internally.
It seems to mean that the data subscribed already is in the client local buffer, not server.
Could you give me any suggestion?
When a client does PUBLISH, this command immediately pushes the message into all sockets that are interested in it. The message is not stored in redis. If a client wasn't subscribed at the time of publishing, he will never see the message.
I'm not familiar with python driver for redis, but judging from the names, I'd guess that listen sends a SUBSCRIBE command and get_message takes a message from the local buffer.
Redis pubsub is fire and forget.
In other words, when a publish command is sent, the message is received by online subscribers, and who wasn't subscribed/listening for messages when the publish command was sent, won't never get these messages.
I have an XMPP client working with Google's GTalk XMPP server. I'd like to make it so that my JID/resource can receive messages from anyone (whether they are subscribed to me or not). Right now, if a client sends a messages to my username without being subscribed, Google's server returns a service-unavailable error (as it should).
<service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
But, I'd like to make it so that the message would go through. The use case here is to provide a public support chat entity so that users can chat me but I don't want them to be subscribed to all my activity (like status messages, etc)
Google Talk explicitly blocks messages from entities you don't share presence with as a spam prevention measure. You can't turn that off, I'm afraid.
Here is my deal:
I have a websocket pubsub server written in python with autobahn websocket (based on twisted).
I have simple website that is connected to the server and subscribed to one channel
Next to this I have simple Django project with one app
And at last I have opened terminal with curl get request that hits my Django app
After request form curl hits my django app and my view I need to send message to the server to the channel that my website is subscribed on. Basically I need websocket client that can send message to specific channel and can be run in django view (no infinite blocking loop).
I've tried to figure out this over 4 days. I've wrote to writ autobahn pubsub client with twisted.reacotr, but I can send the message only once (after I stop reactor to finish django request I cannot start it again, because it's not restartable).
I've olso tried djagno-socketio, but there is but, so I cannot see clients when I try to send the message from django view.
ws4py doesn't support channels
Thanks for any advice. Great would be an example.
You should be able to run Django and Autobahn within 1 server:
Here is an example that shows how to use Flask/WSGI with Autobahn. And Django can run in a WSGI container as well.
Also it should be possible to run an Autobahn-based WebSocket client from a Django/WSGI/Twisted based server using above method as well.
The point is: Twisted can act as a WSGI container and will then run the WSGI Web app (which can be blocking) on a background pool of worker threads. This will allow you to use the asynch features of Twisted, and e.g. run Autobahn - either client or server. So you might also rethink the overall architecture: why run the Autobahn server as a different process at all?
I'm using GAE + Python to create an application that needs to send real-time updates of sensitive data to clients and I wanted to know if the App Engine Channel API is secure or not. Will using HTTPS be enough or do channels require their own security protocol?
Also, what is the underlying implementation of the App Engine Channel API? Websockets, SSE? It seems like it really only provides one way communication from server to client through the channel, and then has the client use a standard HTTP request to communicate with the server.
Connections to the channel API are made over HTTPS, regardless of how your page was loaded, so it's not possible to eavesdrop on the contents of a channel API connection. As long as you keep the channel key secret, then, your channel is a secure communications channel between your app and the client.
Channels are implemented using long polling (comet).
Because channels are long-term-alive connections between server and a client, channels are not allowed to use resource consuming security approaches in many cases due to performance consideration. As it is declared in the official manual, The server only receives update messages from clients via HTTP requests. And as far as I know, even Dropbox sends its long-term notify message via HTTP, using a very short notify only to tell whether there is something new.
Fortunately, there are two ways to ensure your security.
Only notify your client via the HTTP channel when some states change. After that, let the client decide whether a further request, which can be a secure communication, should be made. And this is the most common way channels are used.
Although this is not the way I personally recommended, you can encrypt your data yourself and put these encrypted data run on the insecure HTTP channel.