I'm writing a python real-time chat feature embedded in a web app. I'm a little bit confused on the real time implementation. I need to push real time message to different users.
I plan to use websocket but I'm not quite sure how to save those sockets into an array so that once a user send a message to server, the server can find the related socket and push the message.
So any idea about this? Or what's the common way to implement real time chat feature?
Thanks in advance.
You need to use a websocket aware web server, like Tornado to handle websocket traffic. To multiplex chat messages between different chats and users, there are solutions like Redis and ZeroMQ that you can use for message multiplexing.
However, it sounds like you have zero experience and starting point, so starting with an working example is better approach. Please study existing real-time chat implementations for Python:
https://github.com/heroku-examples/python-websockets-chat
https://github.com/nellessen/Tornado-Redis-Chat
https://github.com/tornadoweb/tornado/blob/master/demos/websocket/chatdemo.py
http://ferretfarmer.net/2013/09/05/tutorial-real-time-chat-with-django-twisted-and-websockets-part-1/
Related
I need to implement a chat application for my web service (that is written in Django + Rest api framework). After doing some google search, I found that Django chat applications that are available are all deprecated and not supported anymore. And all the DIY (do it yourself) solutions I found are using Tornado or Twisted framework.
So, My question is: is it OK to make a Django-only based synchronous chat application? And do I need to use any asynchronous framework? I have very little experience in backend programming, so I want to keep everything as simple as possible.
Django, like many other web framework, is constructed around the concept of receiving an HTTP request from a web client, processing the request and sending a response. Breaking down that flow (simplified for sake of clarity):
The remote client opens TCP connection with your Django server.
The client sends a HTTP request to the server, having a path, some headers and possibly a body.
Server sends a HTTP response.
Connection is closed
Server goes back to a state where it waits for a new connection.
A chat server, if it needs to be somewhat real-time, needs to be different: it needs to maintain many simultaneous open connections with connected clients, so that when new messages are published on a channel, the appropriate clients are notified accordingly.
A modern way of implementing that is using WebSockets. This communication flow between the client and server starts with a HTTP request, like the one described above, but the client sends a special Upgrade HTTP request to the server, asking for the session to switch over from a simple request/response paradigm to a persistent, "full-duplex" communication model, where both the client and server can send messages at any time in both direction.
The fact that the connections with multiple simultaneous clients needs to be persistent means you can't have a simple execution model where a single request would be taken care of by your server at a time, which is usually what happens in what you call synchronous servers. Tornado and Twisted have different models for doing networking, using multithreading, so that multiple connections can be left open and taken care of simultanously by a server, and making a chat service possible.
Synchronous approach nevertheless
Having said that, there are ways to implement a very simple, non-scalable chat service with apparent latency:
Clients perform POST requests to your server to send messages to channels.
Clients perform periodical GET requests to the server to ask for any new messages to the channels they're subscribed to. The rate at which they send these requests is basically the refresh rate of the chat app.
With this approach, your server will work significantly harder than if it had a asynchronous execution model for maintaining persistent connections, but it will work.
If you're going to make a chat app, you'll want to use websockets. They'll make getting updates to all clients participating in a conversation significantly easier and it'll give you real time conversations within your app. Having said that, I've never seen websockets used within a synchronous framework.
If it's OK to make Django-only based synchronous chat application? Too many unanswered questions for a reasonable answer. How many people will use this chat app? How many people per conversation? How long will this app be around? If you're looking to make something simple for you and a couple friends, make what you know. If you're getting paid to make this app, use websockets and use an asynchronous framework.
You certainly can develop a synchronous chat app, you don't necessarily need to us an asynchronous framework. but it all comes down to what do you want your app to do? how many people will use the app? will there be multiple users and multiple chats going on at the same time?
I'm trying to build a Pyramid app that uses ZeroMQ to provide a very simple chat/messaging interface, but I can't seem to figure out the proper setup/workflow.
The structure seems straightforward enough to me, and in its simplest form could be described in as little as two Pyramid "views"/routes:
The client SSE "show messages" view: This view/route would remain open to the client (using Server-Sent Events on the client-side and Pyramid's response.app_iter on the server-side), listening for messages from ZeroMQ and yielding them up to the client as they are received.
The "submit a new message" view: This view/route would receive POST requests containing a single message's data, which it would then pass to ZeroMQ to be received in the SSE view and displayed to any clients listening there.
For some reason however, I have not been able to come up with the correct recipe for accomplishing this feat. Google seems to be pretty sparse when it comes to recipes for 0MQ and Pyramid, and all of my own hacking has either resulted in Python/Pyramid thread/process problems, or 0MQ never being able to send or receive any messages (which is probably related to my threading issues).
So, how does one properly build this kind of an app with Pyramid?
P.S. You may assume any version of Python/Pyramid, etc in your answers. The point is to just get something that works as described.
I made a proof of concept of exactly that a few years back.
https://github.com/antoineleclair/zmq-sse-chat
I want to be able to schedule delivery of a lightweight message from a server to a client. This is new territory to me so I'd appreciate some advice on the possible approaches available.
The client is running on a Raspberry Pi using node.js (because I'm using node libraries to control a piece of attached hardware). Eventually there will be multiple clients like it.
The server could be anything, though I'm most familiar with Python, django and node.
I want to be able to access the server from a browser and cause it to schedule a future message to the client, effectively a push notification with a tiny bit of data.
I'm looking at pub-sub and messaging systems to do this; I started writing a system that uses node on both ends and sockets, but the approach I want is more fire-and-forget occasional messages, not constant realtime data exchange. I'm also not a huge fan of the node-cron style scheduling, I'd like to be able to retrieve and alter scheduled events and it felt somewhat heavy-handed to layer this on top of a cron system.
My current solution uses python on the server (so I can write a django web interface) with celery and rabbitmq, using a named queue per client. The client subscribes to that specific queue using node-amqp, and off we go. This also allows me to create queues that multiple clients can be interested in, which is a neat bonus.
This answer makes me think I'm doing the right thing -- but as I'm new to this stuff, it feels like I might be missing something. Are there alternatives I should consider in the world of server-client messaging?
Since you are already using python you could take a look at python remote objects, (pyro).
I am planning to integrate real time notifications into a web application that I am currently working on. I have decided to go with XMPP for this and selected openfire server which i thought to be suitable for my needs.
The front end uses strophe library to fetch the notifications using BOSH from my openfire server. However the notices are the notifications and other messages are to be posted by my application and hence I think this code needs to reside at the backend.
Initially I thougt of going with PHP XMPP libraries like XMPHP and JAXL but then I think that this would cause much overhead as each script will have to do same steps like connection, authentication etc. and I think this would make the PHP end a little slow and unresponsive.
Now I am thinking of creating a middle-ware application acting as a web service that the PHP will call and this application will handle the stuff with XMPP service. The benefit with this is that this app(a server if you will) will have to connect just once and the it will sit there listening on a port. also I am planning to build it in a asynchronous way such that It will first take all the requests from my PHp app and then when there are no more requests; go about doing the notification publishing stuff. I am planninng to create this service in Python using SleekXMPP.
This is just what I planned. I am new to XMPP and this whole web service stuff ans would like to take your comments on this regarding issues like memory and CPU usage, advantages, disadvantages, scalability issues,security etc.
Thanks in advance.
PS:-- also if something like this already exists(although I didn't find after a lot of Googling) Please direct me there.
EDIT ---
The middle-level service should be doing the following(but not limited to):
1. Publishing notifications for different level of groups and community pages.
2. Notification for single user on some event.
3. User registration(can be done using user service plugin though).
EDIT ---
Also it should like to create pub-sub nodes and subscribe and unsubscribe users from these pub-sub nodes.
Also I want to store the notifications and messages in a database(openfire doesn't). Would that be a good choice?
It seems to me like XMPP is a bit of a heavy-weight solution for what you're doing, given that communication is just one-way and you're just sending notifications (no real-time multi-user chat etc.).
I would consider using something like Socket.io (http://socket.io) for the server<=>client channel along with Redis (http://redis.io) for persistence.
I currently have a one-page Bottle project working through localhost:8080.
For the purposes of this question, assume that single page is naught but a basic short-polling chat, retrieving chatline objects from Python that contain only the sender's name and the body of the message.
Those chatline objects are stored in chat objects, with the project allowing multiple chats.
The chat and sender is determined by the URL. For example, if a chatline is sent from localhost:8080/chat/23/50, it is sent to chat 23 as sender 50, and localhost:8080/chat/23/* will display all chatlines of chat 23 in a basic overflow:auto div.
The current short-polling AJAX requests data from Python once every second. I want to make things more real-time and have decided to go with long-polling (although if you love HTML5 WebSockets, I wouldn't mind learning about them too).
My question is in two parts:
How would I go about implementing a long-poll approach in such a chat system, preferably while still using Python's Bottle module?
How would I then deliver the project through an actual server, accessible externally (i.e., not only from localhost)? Even making it available through LAN would be good.
I'm aware that long-polling can cause severe performance issues with servers such as Apache and would appreciate it if that fact could be factored into any answers; I'd like as scalable a solution as possible.
Any help is appreciated!
I recently attended a presentation about a real-time client-server application that made great use of gevent on the Python/server side and socket.io on the client side. The speaker, Alexandre Bourget, released a gevent-socketio module ongithub, that can be used to make all the plumbing easier.
Everything worked with HTTP long polling only (but socket.io contains all the logic to switch to HTML5 WebSocket or Flash socket). Although the framework was Pyramid, I believe it should work with Bottle too!
I didn't try myself but I think you can use bottle together works with Tornado http://www.tornadoweb.org/ (see Tornado - mount Bottle app).
It is possible to make long-polling with Tornado. Look at the tornadio project https://github.com/mrjoes/tornadio.
You may also be interested in http://pypi.python.org/pypi/bottle-tornado-websocket. I never used this one but it looks like the thing you are looking for.
Tornado doc has a section about running in production : http://www.tornadoweb.org/documentation/overview.html#running-tornado-in-production
I hope it helps