I'm trying to get a "communication line" between a server app that uses MQTT for messaging and a web page where I want to see the messages in real time and send back messages to the server-side app.
I use mosquitto, Bottle and gevent on the server and I want to keep it as simple as possible. Using gevent I managed to receive the MQTT messages in a greenlet, put them in a queue and send the messages to the webpage in the websocket procedure which looks like this:
while True:
mqt = queue.get(True)
ws.send(mqt)
I can also send messages from the web page back to the server and MQTT like this (also through a queue):
while True:
msg = ws.receive()
queue2.put(msg)
However I want these two loops to work at the same time on the same websocket. Is there any way to combine them? For example does receive have a timeout? I guess I could use two separate websockets, but that would be a waste if I can do it with only one.
Why not just have messages delivered directly to the page using MQTT over Websockets? There are a number of brokers that support Websockets and the paho JavaScript client allows both subscribing and publishing of messages
Related
I'm extremely new to all of this, but from my understanding, websockets allow for a bidirectional transfer of information between browsers. Vert.x is a library that allows for asynchronous I/O. And sockJS is a JavaScript library that attempts to use websockets for communication, and provides fallback options otherwise.
But if I'm writing something in Java using vert.x, I don't quite understand how the pieces fit together. Does vert.x actually support websockets? Or do I need a combination of vert.x and sockJS to make that happen?
HTTP(s) is a stateless protocol, which means that once its job is done it will be idle till the next job is given.
So lets take an example of chat application, assume A is chatting with B using HTTP protocol. B has sent a message which is in server, now until A refreshes the browser, B's message will not appear. That's stateless behavior.
Coming to sockets, which is not stateless. Sockets use ws protocol which is always connected to the server. Taking the same example, now if B sends a message, A's socket will fetch and display to the browser, without the need to refresh. That's how sockets work.
To serve a webpage you need an http server. Similarly to use sockets, sockets server is needed. Which is provided by Vert.x. So Vert.x will start socket server, your browser will listen to that server using clientside sock.js file.
I have an API running on a server, which handle users connection and a messaging system.
Beside that, I launched a websocket on that same server, waiting for connections and stuff.
And let's say we can get access to this by an Android app.
I'm having troubles to figure out what I should do now, here are my thoughts:
1 - When a user connect to the app, the API connect to the websocket. We allow the Android app only to listen on this socket to get new messages. When the user want to answer, the Android app send a message to the API. The API writes itself the received message to the socket, which will be read back by the Android app used by another user.
This way, the API can store the message in database before writing it in the socket.
2- The API does not connect to the websocket in any way. The Android app listen and write to the websocket when needed, and should, when writing to the websocket, also send a request to the API so it can store the message in DB.
May be none of the above is correct, please let me know
EDIT
I already understood why I should use a websocket, seems like it's the best way to have this "real time" system (when getting a new message for example) instead of forcing the client to make an HTTP request every x seconds to check if there are new messages.
What I still don't understand, is how it is suppose to communicate with my database. Sorry if my example is not clear, but I'll try to keep going with it :
My messaging system need to store all messages in my API database, to have some kind of historic of the conversation.
But it seems like a websocket must be running separately from the API, I mean it's another program right? Because it's not for HTTP requests
So should the API also listen to this websocket to catch new messages and store them?
You really have not described what the requirements are for your application so it's hard for us to directly advise what your app should do. You really shouldn't start out your analysis by saying that you have a webSocket and you're trying to figure out what to do with it. Instead, lay out the requirements of your app and figure out what technology will best meet those requirements.
Since your requirements are not clear, I'll talk about what a webSocket is best used for and what more traditional http requests are best used for.
Here are some characteristics of a webSocket:
It's designed to be continuously connected over some longer duration of time (much longer than the duration of one exchange between client and server).
The connection is typically made from a client to a server.
Once the connection is established, then data can be sent in either direction from client to server or from server to client at any time. This is a huge difference from a typical http request where data can only be requested by the client - with an http request the server can not initiate the sending of data to the client.
A webSocket is not a request/response architecture by default. In fact to make it work like request/response requires building a layer on top of the webSocket protocol so you can tell which response goes with which request. http is natively request/response.
Because a webSocket is designed to be continuously connected (or at least connected for some duration of time), it works very well (and with lower overhead) for situations where there is frequent communication between the two endpoints. The connection is already established and data can just be sent without any connection establishment overhead. In addition, the overhead per message is typically smaller with a webSocket than with http.
So, here are a couple typical reasons why you might choose one over the other.
If you need to be able to send data from server to client without having the client regular poll for new data, then a webSocket is very well designed for that and http cannot do that.
If you are frequently sending lots of small bits of data (for example, a temperature probe sending the current temperature every 10 seconds), then a webSocket will incur less network and server overhead than initiating a new http request for every new piece of data.
If you don't have either of the above situations, then you may not have any real need for a webSocket and an http request/response model may just be simpler.
If you really need request/response where a specific response is tied to a specific request, then that is built into http and is not a built-in feature of webSockets.
You may also find these other posts useful:
What are the pitfalls of using Websockets in place of RESTful HTTP?
What's the difference between WebSocket and plain socket communication?
Push notification | is websocket mandatory?
How does WebSockets server architecture work?
Response to Your Edit
But it seems like a websocket must be running separately from the API,
I mean it's another program right? Because it's not for HTTP requests
The same process that supports your API can also be serving the webSocket connections. Thus, when you get incoming data on the webSocket, you can just write it directly to the database the same way the API would access the database. So, NO the webSocket server does not have to be a separate program or process.
So should the API also listen to this websocket to catch new messages
and store them?
No, I don't think so. Only one process can be listening to a set of incoming webSocket connections.
Situation
Am trying to build a real-time chat toy app using the following technology stack
RethinkDB
Laravel 5
Ratchet
What I perceive to be the conceptual situation
The green arrows represent the real-time exchange of data.
The black arrows represent other non real-time requests and exchange of data.
My question
I was wondering if my understanding of the implementation of chat using the technology stack is correct based on the diagram?
if there are inaccuracies, what would they be?
Your interpretation seems correct, although I would not suggest using the websocket to send data to but only to distribute live data to all subscribers of a channel.
To do this, get an API(preferably) going to receive new posts/chats/users.
And use a push server to send the data received to the socket.
A push server is just an in between of the app and websocket that allows php(laravel) to access the socket easily.
Edit: to elaborate
To retry explaining this to you.
All clients listen to the WebScoket Server. This is a connection which is passive and they will only receive messages from the socket according to what topics/subscriptions they have.
When someone wants to send a message(in case of a chat application) they send it to an API to check if the right user sent it, maybe even use apikeys or other means of security.
Once the message is received in the API then the API wants to distribite it to all listening clients for that chat room/topic/subscription.
So the message is forwarded to the pushserver which is an in between of the backend (API, controllers) and the WebSocket (subscriptions, topics).
The pushserver forwards the message to the WebSocket afterwards and then the WebSocket distibutes the message to the correct listeners.
Advantages of using an API:
Security
Scalability
I was working with different patterns in zeromq in my project and right now i am using req/rep(later will shift to dealer/router) and pub/sub . The client sends messages to the server and the server publishes this information to other clients who have subscribed.
To use multiple sockets i followed the suggestions on this thread
Combining pub/sub with req/rep in zeromq and used zmq_poll . My server polls on req socket and pub socket.
While writing the code and while reading the above post i guessed that my pub socket will never get polledin and that's what i am observing now when i run the program. Only my request is polled in and publish is not happening at all.
If i don't use polling it works fine i.e as soon as the server gets the message i publish it.
So i am unclear on how polling will be useful in this pattern and how i can use it ?
You probably don't need to poll the pub socket. You certainly don't need to poll in on it - because that can never be triggered (pub sockets are send only).
The polling pattern might be useful in the case where you want to poll for "ready to send" on the req and the pub socket, allowing you to multiplex those channels. This will be particularly useful if/when you move to using a dealer/router.
The reason for that is that replacing req with a dealer (e.g.) can allow you to send multiple messages before receiving responses. Polling for inward and outbound messages will allow you to make maximum advantage of that.
How can a client both subscribe and listen to replies with zeromq?
That is, on the client side I'd like to run a loop which only receives messages and selectively sends requests, and on the server side I'd like to publish most of the time, but to sometimes receive requests as well.
It looks like I'll have to have two different sockets - one for each mode of communication. Is it possible to avoid that and on the server side receive "request notifications" from the socket on a zeromq callback thread while pushing messages to the socket in my own thread?
I am awfully new to ZeroMQ, so I'm not sure if what you want is considered best-practice or not. However, a solution using multiple sockets is pretty simple using zmq_poll.
The basic idea would be to have both client and server:
open a socket for pub/sub
open a socket for req/rep
multiplex sends and receives between the two sockets in a loop using zmq_poll in an infinite loop
process req/rep and pub/sub events within the loop as they occur
Using zmq_poll in this manner with multiple sockets is nice because it avoids threads altogether. The 0MQ guide has a good example here. Note that in that example, they use a timeout of -1 in zmq_poll, which causes it to block until at least one event occurs on any of the multiplexed sockets, but it's pretty common to use a timeout of x milliseconds or something if your loop needs to do some other work as well.
You can use 2 threads to handle the different sockets. The challenge is that if you need to share data between threads, you need to synchronize it in a safe way.
The alternative is to use the ZeroMQ Poller to select the sockets that have new data on them. The process would then use a single loop in the way bjlaub explained.
This could be accomplished using a variation/subset of the Majordomo Protocol. Here's the idea:
Your server will be a router socket, and your clients will be dealer sockets. Upon connecting to the server, the client needs to send some kind of subscription or "hello" message (of your design). The server receives that packet, but (being a router socket) also receives the ID of that client. When the server needs to send something to that client (through your design), it sends it to that ID. The client can send and receive at will, since it is a dealer socket.