Use the same WebSocket to push messages to a client - concurrency

I'm starting with WebSockets, I already built a chat web-application as an exercise and it went something like this:
Every user has an opened websocket connection at their arrival to the chat-room, and when new messages are available, they're simply pushed to each user. The different messages are then displayed using javaScript.
Now, I'm trying to push the exercise a bit further by creating a one-on-one chat. Basically, there will no longer be a unique chat-room but private chat conversations. A user should be able to talk to different people from the same page. (Something like Google chat or Facebook chat).
After thinking about ways to do so, I came down to two solutions:
Open multiple websocket connections. (if possible)
Use the same connection to handle all opened conversations. Basically, each message that is pushed to the client will carry a field saying to which conversation it belongs, a javaScript will then handle the display of each message under the right conversation.
To me, the second solution seems better than the first. So, my questions are:
1- Will this solution have any performance problems? (Lost messages...)
2- Is there any other-better way of doing this?

The way to go depends (IMHO) on what framework you are using to do this communication.
I (as you) would go for multiplexing (second option) where you use one connection to handle all communication.
I assume that your framework of choice supports publish/subscribe and multiplexing?
I can provide you with a simple example if you like.
Regards
Uffe, Team XSockets

Related

Web API that itself sends data to client on availability

I am currently working with Django but I am stuck as I don't know if I am pursuing the right model given the nature of my application.
Problem Statement:
I have to make a REST API for a client such that whenever I get a trigger for a new entry/entries in my Database I have to send those to the client which is supposed to listen to a URL and has asked for data only once and now is open to receive data whenever available to him.
It is not sending a GET request now and then.
There will be different endpoints of the APIs. One is where I provide him all the new data available to me and in other where it asks for specific data (ex: '/myAPI/givemethis')
I can easily implement the second requirement as it is a simple request-response case.
I am not sure how to send him data that too on availability without him making a repeated request as client.
It appears a Publisher-Subscriber model is better suited for my use case but I don't know how to implement it on Django.
I bumped into several concepts like StreamingServices and MQTT but I am not sure what should be the right choice to go with.
Kindly provide some suggestions.

django-channels databinding on model.save()

I have a channels app that is using databinding. When changes are made with django admin they are being pushed to the web as expected. I have loop set up on a socket connection to do some long polling on a gpio unit and update the db, these changes are not being pushed to the web. Channels documentation says:
Signals are used to power outbound binding, so if you change the values of a model outside of Django (or use the .update() method on a QuerySet), the signals are not triggered and the change will not be sent out. You can trigger changes yourself, but you’ll need to source the events from the right place for your system.
How do I go about triggering these changes, as it happens with admin?
Thanks and please let me know if this is to vague.
The relevant low-level code is in lines 121-187 of channels/binding/base.py (at least in version 1.1.6). That's where the signals are received and processed. It involves a few different things, such as keeping track of which groups to send the messages to. So it's a little involved, but you can probably tease out how to do it, looking at that code.
The steps involved are basically:
Find the right groups for the client
Format your message in the same way that the databinding code would (see this section of the docs)
Send the message to all the relevant groups you found in step 1.
Alternatively, you might consider using a REST API such that the socket code submits a POST to the API (which would create a database record via the ORM in the normal way) rather than directly creating database records. Your signals will happen automatically in that case. djangorestframework (server-side) and requests (client-side, if you're using python for the long-polling code) are your friends if you want to go that way, for sure. If you're using another language for the long-polling client, there are many equivalent packages for REST API client work.
Good luck!

Is REST a good solution if you have lots of requests?

I want people to controll my arduino robot via the internet. It's important that the controlling reacts very fast. The user may send many requests per second.
Let me explain my architecture:
The user connects to a web-frontend. He can use a virtual joystick and buttons. The frontend will then send orders (like "motor1:255" "motor2:0"....) to an application server (Wildfly).
When a frontend-session starts, Wildfly will establish a connection to my computer or smartphone using a socket. The orders will be passed to the arduino using bluetooth. When a frontend-session is not longer active, the socket will be closed.
One Wildfly should be able to controll up to 10 robots. One robot can be controlled by exactly one user. Some developers use a mysql table and add a row for each incoming order. I don't think this would work in my case.
Is it okay to use REST to send the orders from the frontend to the application server? Is there any other fast and secure way to transport the user input from the frontend to the business logic?
Goot
REST, when properly understood and applied, is a solution for problems of long-term evolution and maintenance of your application. It doesn't seem to be your case.
What you mean is probably if an HTTP API is a good solution if you have lots of requests, and the answer is, it depends. I'd probably look into something like ZeroMQ for doing what you want.

Publish/Subscribe/Request for exchange of big, complex, and confidential data?

I am working on a project where a website needs to exchange complex and confidential (and thus encrypted) data with other systems. The data includes personal information, technical drawings, public documents etc.
We would prefer to avoid the Request-Reply pattern to the dependent systems (and there are a LOT of them), as that would create an awful lot of empty traffic.
On the other hand, I am not sure that a pure Publisher/Subscriber pattern would be apropriate -- mainly because of the complex and bulky nature of the data to be exchanged.
For that reason we have discussed the possibility of a "publish/subscribe/request" solution. The Publish/Subscribe part would be to publish a message to the dependent systems, that something is ready for pickup. The actual content is then picked up by old-school Request-Reply action.
How does this sound to you??
Regards,
Morten
If the systems are always online, it sounds good.
You might want to look at PubSubHubbub because:
1. Don't solve a problem that has already been solved 2. It is scalable and represents a good separation of concern.
It involves 3 parties:
Publishers (who publish stuff)
Subscribers (who are interested in certain publications)
Hubs (who mediate and get rid of 'polling')
It works in the following way:
A subscriber, registers their interest in a URL with a Hub and provides a callback URL.
A publisher, notifies the hub when publishing content.
A hub fetches the 'delta' and pushes it to interested subscribers.
The protocol itself is an extension to Atom, but it seems to fit your requirement, e.g. the new Atom 'content' could be an item containing URLs to newly published documents (which can then be downloaded separately).
New/modified documents => new/modified items in feed containing URLs to fetch them => Hub => Subscribers => Pull documents from Publisher
I don't have a great experience about this, but a messaging queue should help you accomplish what you need. I am using such a system while managing publishing data to multiple front end clients from a backend.
If the client is off, the data is not consumed and the server receives no acknowledgement of data being reveived. Once the client comes back online he consumes the data and remains listening for more messages onve the queue is clear. And ofc the publisher receives a ack for data being consumed. In this way we can identify and notify people who have problems at the receiving end as a bonus. Could this do it in your case?
This approach works if the dependent systems are always online - you can't send messages to PCs that are turned off for the night/weekend.
So if the clients are servers that run 24/7, this works. Otherwise, try this approach:
Let clients register themselves
When new documents come in, add an entry "client X needs to see this" in your database
When clients connect, send them all the entries.
When clients successfully downloaded a document, delete the "client X needs to see this" entry. That keeps the work table small.
This has several advantages:
Clients don't need to run 24/7
The flag is only removed after the client has seen the document (so no updates can be lost).
You have one place where you can see which client never pulls it's documents. A simple select client, count(*) group by client having count(*) > 10 tells you about problems.
Most clients will fetch their data timely, so the work table will stay small. That means there is little overhead when you have to collect the "what's now" data.
EDIT The problem with off-line subscribers is that they don't know what they're missing. So the sending side needs to keep track of the failed push/pull requests. Which means you must implement my suggested pseudo-code to make sure broken connections can be resumed.

A couple of questions for a websocket app

I'm currently using Jetty as my websocket server and I'm trying to make a real-time game. I'm really new to this. So far I've managed to work on the easiest one (which is the chat). Now, I have a couple of issues:
I'm trying to make a list of the current users connected in the server; how do I make such feature? I don't really know if this is practical but my idea is that there's a time interval that lets the server know that "Hey, I'm still alive." I want my user list to be dynamic in such a way that if a user logs out, the list will refresh.
I'm also trying to make "rooms" for my app. Basically, the people in "Room 1" can't see what people in "Room 2" are doing; the other room functionalities are already self-explanatory. I still don't have an idea for this; can someone recommend a way to implement this?
So far I've been having fun in learning this technology, and I would be very glad if there would be incoming help. These two are my issues so far. I'm also open for any suggestions for my app.
Thank you all in advance. :-)
(Uhm, can #1 and #2 be solvable solely by Javascript?)
Your question isn't really jetty or websocket specific.
Websockets simply provide a transport mechanism for your web browser to communicate with the server - what gets set over that transport, and how the server manages information are completely separate to the websocket.
Firstly, if you haven't read it already, read this article: http://cometdaily.com/2010/03/02/is-websocket-chat-simple/
Secondly, consider using cometd to make this easier - version 2 (currently in Beta) supports websockets.
As for your questions - there are 2 things you'll need to do (cometd can help with this)
1. Define a protocol
Define a messaging protocol to sit on top of websockets. Websockets just provide a way to send chunks of data around, they don't define what that data means. You'll need to build something that does that, so you have messages that go from the client to the server like.
CONNECT "user"
STILL_ALIVE
JOIN_ROOM "room1"
LEAVE_ROOM
GET_USER_LIST
SEND_MESSAGE "message"
And then you need messages form the server to the client
RECEIVE_MESSAGE "user" "message"
RECEIVE_USER_LIST "room1"
You need to come up with some reliable way to send that data over a websocket. You can invent your own simple protocol (like the Jetty chat example does), you could use JSON, or XML, or CometD channels.
2. Server-Side State
If you've got simple chat working, then you must have made a start on this, but the other bit you need is a way to keep track of
how many users are connected
what their names are
which socket they're connected to
which room they're in
Depending on how complex your system is going to become, you might be able to just store that in 1 big singleton on the server.