How to emit different messages to different users based on certain criteria - python

I am building a chat application using flask socketio and I want to send to a specific singular client and I'm wondering how to go about this.
I get that emit has broadcast and include_self arguments to send to all and avoid sending oneself, but how exactly would I go about maybe emitting to a single sid?
I've built this application using standard TCP/UDP socket connection where upon client connecting, there socket info was stored in a dictionary mapped to their user object with attributes that determined what would be sent and when I wanted to emit something to the clients I would iterate through this and be able to control what was being sent.
I'm hoping some mastermind could help me figure out how to do this in flask socket io

To emit to a single user, you can use the user’s sid. For more info on that, visit this discussion.
If you have access to the client application, you could set up different rooms, let the clients join the different rooms according to your criteria, and have your server application emit to the different rooms. For more info on that you can have a look at the socket.io documentation about rooms and namespaces and the python-socketio documentation about rooms.

I ended up figuring it out. Using the flask request module, you can obtain the users sid using request.sid, which can be stored and emitted to within the room parameter emit(..... room=usersid

Related

Passing data between apps in Python

I have a question about implementing passing data between two apps that I have running.
I have a Flask backend, which receives a user email via a POST request and stores it in a variable. I need to pass this variable into TelegramBotAPI.
What I need to happen is when Flask receives a new user email, it will pass the data into the TelegramBotAPI and trigger a function which will send it in a message to the user.
How do I go about implementing this?
Assuming your architecture separates the TelegramBot from the Flask server, you would treat your flask server as the client for your Telegram Bot which is the server in this scenario.
Armed with this information there are numerous ways to go about this. TelegramBot could provide an http server through which clients could send requests. Another option which requires less availability from the Bot but ensures eventual consistency is using a message broker like RabbitMQ.
Lastly, if you wish to store the email permanently you should consider using a storage like a Database (for robustness) or a File system (if you have only one server)

Is Django Channel Appropriate implementing Optimistic Chat application like telegram or whatsapp?

I had implemented a real-time chat application web service which gives services to the web and mobile client. I found that channel makes separate sockets for every user and bind them in groups and rooms in Redis handling where a specific socket message should be sent.
So in this case, for example, the mobile platform has to save which sockets belong to which rooms and groups and in every message sending from the server, the mobile platform has to check what room this message belongs and send it on. think big like telegram and WhatsApp. it seems to me that it's not appropriate client saves multiple sockets for every user communicating with one server. Am i right??
Also in cases like WhatsApp(large scale applications) servers have sockets for every user in every room if they choose the Django channel. it makes a lot and lots of ports busy on the server.
I have experience implementing socket implementation using Redis, SocketIo, Laravel to. using these tools, I was free to use few sockets for sending all kinds of notifications to users using few socket ports. it was seemed lighter than Django channel.
With these kinds of thinkings, I have doubt to continue using Django channel in my project, and I am a little worried about when it deploys in large scales.
Should I be worried??

How do you pass variables using a HTTP post from a JS file/function to a separate python file/function hosted somewhere else?

I have JS running and essentially getting user entries from my HTML session storage and pushing these to a DB. I also need to use a HTTP request to pass a json object containing the entries to a python file hosted somewhere else.
Does anyone have any idea of documentation I could look at, or perhaps how to get JSON objects from JS to Python.
My client does not want me to grab the variables directly from the DB.
You have to create some sort of communication channel between the javascript and python code. This could be anything, SOAP, HTTP, RPC, any number of and flavor of message queue.
If nothing like that is in place, it's quite the long way around. A complex application might warrant you doing this, think micro services communicating across some sort of service bus. It's a sound strategy and perhaps that's why your client is asking for it.
You already have Firebase, though! Firebase is a real-time database that already has many of the characteristics of a queue. The simplest and most idiomatic thing to do would be to let the python code be notified of changes by Firebase: Firebase as service bus is a nice strategy too!

XMPP based live-chat system in Django

I need to implement an XMPP based live-chat system in Django. After a lot of scourging and ideas from a colleague, we came up with this.
Method using a bot:
When a visitor visits the site. The visitor's XMPP client which in this case is Strophe.JS begins an XMPP-over-BOSH connection to the XMPP server and connects to a room called <visitor_id>#conference.demo.com. Currently there is no one else in the room.
The visitor makes an analytics request with a custom visitor id to Django
The Django view, stores the visitor id in a table called ActiveUsers. This table contains a new field as well called status. It sets the status to INACTIVE.
This model dispatches a signal on the save method.
This signal gets picked up by a bot which connects to the XMPP server and joins the room <visitor_id>#conference.demo.com. Now we have the user and the bot in the room.
The site support people are logged into their web interface.
They have JS code that keeps long-polling the Django site to check the ActiveUsers. It fetches the rows from the table and displays it. (I've thought of using django-pubsub for this)
When the visitor types a message, it goes via XMPP-over-BOSH to the XMPP server, the jabber bot in the room see this message and updates the status of the record in the ActiveUsers table to ACTIVE.
As said: The site support people have JS which keeps polling this table. It begins blinking the ow to show that the user is now chatting.
The support personnel can now double-click that row which on doing so begins an XMPP-over-BOSH connection to the visitor's room. It knows that the room is <visitor_id>#conference.demo.com.
The bot seeing that the support person has joined the room, updates ActiveUsers record to show CHATTING. This ensures that no more than support personnel can be in the room i.e. room occupied.
The bot logs the messages to a Django table
When the both sees that both users have left the room, it deletes the record.
ejabberd or openfire will be XMPP server.
Apache is the web server which runs mod_wsgi for serving Django and mod_proxy for proxying the XMPP-over-BOSh requests to the XMPP server.
Does this sound like a good of doing this? Any suggestions? I'm worried about the load on the Django system.
(It's long. Sorry 'bout that.)
Method using Presence Stanzas:
On the client side, i'm using Strophe JS library which supports presence and I had add callback methods. I'm flexible with using ejabberd or openfire as my XMPP server. The are many visitors on the XMPP server — some from site A and some from site B but they are all connected to the same XMPP server. When the visitor visits the site, they are connected to the XMPP server as <visitor_id>_<site_id>#demo.com and each one gets logged into a room called <visitor_id>#conference.demo.com. The sales/support personnel are also connected to the XMPP sever as <supportsale_id>_<site_id>#demo.com. They are not connected to any chat room though. They don't have any of the visitors on their roster.
A good way of showing that a user has connected to the site would be to pass a presence stanza to the sales/support people. Only visitors and sale/support personnel from the same site communicate with each other and that's why I have the <site_id> in the username to show which site that person belongs to.
It seems that you can't subscribe to presence stanzas for a user if you don't have him on your roster. (Quite logical). Is is possible to automatically add every new user of a site connecting to the system to the roster of the sales/support people of that site? Wouldn't this then automatically signal a presence to the sales/support people? How can I implement this — any help?
I wrote exactly this. It's called Seshat and uses a "broker" bot between the website and a Jabber server (I use ejabberd). It's in beta right now mainly because it hasn't been extensively tested outside my company.
Note: while the README specifically mentions the Pyramid web framework, the core system would work just as well with a Django, TurboGears, or command line system. It's just that I only package example code showing how to integrate it with Pyramid.
Seshat is being actively developed. If you have any feature requests, let me know. :-)
I'm not sure you need to use MUCs to implement this. Your bot could maintain its own pubsub node which it is subscribed to. When a new user begins to type it could send a notification to the pubsub node, which the bot would then see. From there, the bot could notify a support person via XMPP, thus eliminating the need to long poll the database table. Then the support person could start a standard one to one chat session with the end user. In addition, their presence could be set to 'na' in order to show that they are in a session with a user.
I think that it's better to use presence stanzas to "signal" any (in)activity. What you need to store in database is only the persistent data you need for further analysis. Otherwise, I think you'll have great time coding the application :).
EDIT:
function onConnect(status) {
if (status == Strophe.Status.CONNECTED) {
var joined = false;
var participants = {};
$('#events').html('<text class="textmainleft">XMPP connection established. Ready to rock n roll!</text>');
connection.send($pres().c('priority').t('-1'));
connection.addHandler(notifyUser, null, 'message', 'groupchat', null, null);
connection.send($pres({to: 'groupchatroom#conference.demo.com/' + nickname}).c('x', {xmlns: 'http://jabber.org/protocol/muc'}));
} else if (status == Strophe.Status.AUTHFAIL) {
$(location).attr('href', AUTHFAIL_URL);
} else if (status == Strophe.Status.CONNFAIL) {
$(location).attr('href', AUTHFAIL_URL);
}
}
$(document).ready(function () {
connection = new Strophe.Connection(BOSH_SERVICE);
connection.connect(jid, password, onConnect);
});
notifyUser is another function (just link onConnect) that would handle the received message stanzas.

How to do cloud computing with Python and Java? Final Year project

For my final year project I plan to code a cloud in Python. The client will be written in Java by the other member of my team. The client will have a tabbed interface and it will provide a text editor, a media player, a couple of small Java based games and a maybe a few more services.
The server will work like this:
1) Validate the user.
2) Send a file, called "dump" to the user. Dump will contain all the file names and file types that the user created by himself or the files which the user can read/write. This info will be fetched from the database.
3) The tabs in the client will display the file types associated with the tab application. e.g the media tab will only select and show the media files from the dump readable by user. The text editor tab will show only the txt files from the dump readable by the user.
4) A request to open the file will send the file back to client, which the associated application will open.
5) All the changes made to the files and all the actions (overwriting, saving, deleting etc.) will be sent back to the server along with the new object. Something similar will be done to the newly created objects.
My Questions are:
What are the best approaches for the communication between the client and the server. For the dump I plan to use some sort of encrypted XML file. For the other way round, I don't have a clue :/.
For easy integration with the database, I was planning to use Django (which I started few days back). How can I send my requests from the client to the server (without Django I'd use SQL queries) and the files from the server to the client? Maybe GET and POST will work for the former problem? Any other suggestions?
Q1: how should I transfer data between client/server securely
A: HTTPS to support encryption & JSON to serialise objects between languages (Python/Java) seems to be the most natural. You could experiment with XML-RPC over SSL or TSL if you want to be creative.
Q2: How do I send queries to the server's db?
A: My first response is to say talk to the person coding the server, and see what's easiest on that end. However, I think that your client should stick to HTTP. The server developer would ensure the server supports RESTful URIs. Then your client only access a URI and have the results processed by the server.
At its most raw, this could be implemented like this:
https://www.example.com/db?q="SELECT * FROM docs"
There are smarter ways to do it, but you get the idea.
If you're going to use a web framework on the server, it makes sense to use an HTTP-based protocol. The downside is that only the client can initiate a connection (e.g., the client needs to first ask for the "dump" file), but a simple GET request will suffice (remember, the server can send anything in the HTTP response, including your XML file).
Regarding encryption, it's best to use an existing protocol like HTTPS. There are well-vetted libraries that will correctly establish a secure connection between your client and the server.
Overall, I'm advocating the highest-level protocols that are appropriate for your application. HTTP(S) goes hand-in-hand with your web-based architecture, so make use of it.
Stick to Django. It's really productive. I would use JSON instead of XML. More convenient. import json. This should help you in communicating between client-server.
Also cloud computing is just a recent word that's just thrown around for (client+server+some services). Oh by the way all that you want to do can be completely done in Django itself. No need to go to JAVA.
Django is Cool :)

Categories

Resources