I have this situation where I need to store data in a database and emit an event to only specific sockets. This can be done in two ways :
Emit an event from the client side, listen to that event on the sever side, store the data and emit the event to sockets we want.
Send a http request to the server, where I store the data and emit the event to sockets.
I was wondering which one of these methods is efficient and is there any better solution to the use case than these two.
I would say that if you are already using SocketIO, it might be a good idea to go with option 1, emiting an event from the client side. I am not sure how your application is structured, but I presume that when you use SocketIO in the first place, you will do all your server side communication through there anyway.
HTTP requests have an obvious overhead to them as they - at the very least - send headers to the server.
However when you begin long polling you'll always need to make sure that it doesn't create a massive load on the server. Now I see that you have node.js in your subject, which I hope is what you use. If that is the case, then this will not create any problems as node.js is very good in handling these requests at almost no cost of system resources.
Disclaimer: I am no expert on the raw technical details which is best or not, I am a mere developer with an opinion. I don't mind down voting, but please let me know why so we can all learn.
Related
The logic of my code is basic.
The user sends a request to the server side, where it is processed and shown in an admin panel. Afterwards a person with access to the admin panel analyses the data and sends a response with some delay.
How can I create a response listener on the client side, so that I can catch the message I get from back-end, no matter the delay?
I tried doing it with fetch, but no wonder it didn't work, because once it is compiled, it makes the action immediately. Is AJAX an option in my case?
You'll need to have some sort of bidirectional communication layer here. The most common approaches are polling, web hooks, or sockets. Polling will probably be the easiest to set up in a beginner use-case.
If you're referring to jQuery's $.ajax, which uses XMLHttpRequest, it's not likely to be a good idea unless the server can respond very quickly every time. From what I understand, if the request isn't fulfilled within a reasonably short period of time, the browser or OS will terminate it. Fetch might have different limitations, but I still wouldn't trust it for something like this.
There are better approaches. Either create a websocket, so that the server can push information to the client on demand, or (less elegant) have the client repeatedly make requests to the server (say, every minute) and have the server respond positively if/when the admin panel has been dealt with.
So basically I'm working with a server in PHP and client in JS and I need to implement a way of sending updates to clients.
There's a long polling that we want to replace for something more efficent so we were thinking in SSE but I want to send the data to a specific client after I do an INSERT into the database in a specific action.
So I have some questions about it
Do I need to connect the EventSource from the client to the action that makes the INSERT to have access to it from there?
It is possible to connect the EventSource to some action and not run the code in it?
Because I'll like to have the connection available to send data after the INSERT but I don't want to run the code every time the EventSource reconnect. Is any of this possible or should I use some other technology like WebSocket?
Thanks and sorry if my english sucks. Hope you understand my question.
Your SSE connection in PHP is a dedicated process (for each client). There has to be code there, but in your case it will be as simple as hanging around waiting for a signal that the INSERT has happened.
This is all likely to be identical to how your current long poll solution works?
There's a long polling that we want to replace for something more efficent
...
should I use some other technology like WebSocket?
It depends on in what way long poll is inefficient, but I'd expect the bottlenecks to not change.
SSE is really just a HTML5 standard, wrapped around how long poll works. And WebSocket is the same, except it is two-way (and trading more flexiblity for more complexity). In all three cases you are keeping a dedicated socket open (*), and there has to be a process on the server handling that connection.
*: Less of an issue with http2 multiplexing.
I am trying to implement a simple UI which shall be showing the logs written in my server console. Have searched but couldn't find a solution which satisfies my requirement.
As per my design, I have a java program using Apache common-io api for tailing log file. It helps me to reduce memory overhead, I do not want to keep large chunks in memory.
So when client makes a request, server shall start reading file and send the read data incrementally and shall keep showing until client stops receiving. I do not wish to send multiple request because that would make application read file again and again adding to which I would need to maintain a state/offset (possible solution but avoiding it).
I tried to check for JAX-RS using Asynchronous Response but that doesn't seem to help. I am not sure if HTTP/2 is gonna help.
Please help me understand how this can be achieved, and if I would need to implement socket programming at client and server side or if there is any such protocol which can be used. I am open to modify tech stack.
Thanks
You can use any protocol that supports long lasting streaming connections (which there are many).
If you're already using JAX-RS, then StreamingOutput might be what you want.
After bit of more searching I finally found a bunch of ways of achieving what I mentioned. Before I would like to explain how it cannot be achieved using HTTP (Rest specifically).
HTTP Way: There are few ways in HTTP and/or HTTP2 where you can create a long lasting connection using long-polling in both versions or using multiplexing property present in http2. In both cases the underlying protocol in TCP so there not much difference. However, in HTTP/HTTP2 transactions occur in a fashion where once server receives a request and sends response back, it doesn't expect client to receive response again neither client expects to receive one. So one complete cycle includes a pair of request and response. Hence, if you try to send another response you cannot do that because neither client nor server would be able to receive or send that respectively. There are many resources in Google for more in-depth information.This has a good explanation and references
So I tried to check if I can use some socket coding in order to keep the connection alive and transmit data. Luckily I stumbled upon another way to achieve that.
Two of which I felt make more sense for my requirement are as follows. I would not try to explain them just to avoid providing wrong information here since I myself am trying to get more insight.
1. Server-Side Events(SSE)
2. WebSockets
This will give a fare idea about them.
I am updating an old system that used to use an ajax polling mechanism. The script would periodically call the back-end looking for updates, and rarely the user would make an ajax request to send data. I first wanted to use Web Sockets because I could instantly get the data from push events, and because the connection stays open. I then read about Server Side Events, and how it is one directional. This fits exactly what I need because the browser is just waiting for events. However, there are rare cases when the user can send data. Is there an alternative to Server Side Events, where I can keep a connection open to send data back to the server? Is it better to use SSE + AJAX, SSE + (Alternative Way), or just a web socket (Even though data is rarely sent back to server)?
Thank you
This is the best explanation for SSE and its flexibilty
Server-Sent Events vs. WebSockets
Why would you choose Server-Sent Events over WebSockets? Good question.
One reason SSEs have been kept in the shadow is because later APIs like WebSockets provide a richer protocol to perform bi-directional, full-duplex communication. Having a two-way channel is more attractive for things like games, messaging apps, and for cases where you need near real-time updates in both directions. However, in some scenarios data doesn't need to be sent from the client. You simply need updates from some server action. A few examples would be friends' status updates, stock tickers, news feeds, or other automated data push mechanisms (e.g. updating a client-side Web SQL Database or IndexedDB object store). If you'll need to send data to a server, XMLHttpRequest is always a friend.
SSEs are sent over traditional HTTP. That means they do not require a special protocol or server implementation to get working. WebSockets on the other hand, require full-duplex connections and new Web Socket servers to handle the protocol. In addition, Server-Sent Events have a variety of features that WebSockets lack by design such as automatic reconnection, event IDs, and the ability to send arbitrary events.
I had built a chat application using sse and ajax for my site.I would suggest sse + ajax would be way to go if there is only stream updates and very few updates from client to server for that you can use the ajax part
Only problem that I found is its lack of support across browsers .And if you want to know more in depth about sse ask specifically what you want
Browser Support List
As you usage is mostly server pushing to client, I would recommend a combination of Server-Sent events for the push from server to client and AJAX for the other way around.
You should definitely read this article to get to a decision:
http://streamdata.io/blog/push-sse-vs-websockets/
This will give you pros and cons of using Server-Sent events versus WebSocket.
I'm currently experimenting with WebSockets in a bid to reduce / remove the need for constant AJAX requests in a potentially low bandwidth environment. All devices are WebSocket compliant so there's no issue there, and I'm trying to keep it to native PHP WebSockets, no node.js or other frameworks / libraries (Which so far has been fine).
What I'm looking to do is to decide how to go about notifying connected clients about an update to a database by another Client. The use case in question is a person pressing a button on their device, which then alerts that persons manager(s) to that press. So the two options I have though of are as follows:
1. Looping a Database Query (PHP)
My first thought was to insert a query into the WebSocket server that is effectively saying "Has the alert field changed? If so, notify the manager(s)". Whilst this is the most straightforward and sensible approach (That I can think of), it seems wasteful to have a PHP script designed to reduce strain on the server, that is now running a query every second, however, at least this would ensure that when a Database update is detected, the update is sent.
2. Sending a notification from the Client
Another thought I had, was that when the client updates the Database, they could in fact send a WebSocket notification themself. This has the advantage of reducing any intensive and looped queries, but also means that I'd need to have a WebSocket message being sent every time I want to change any data, such as:
$.post("AttemptDatabaseUpdate.php", {Data}).function(Result) // Don't worry about the semantics of this, it's not actual code
{
if(Result == "Successful")
{
SendWebSocketNotification(OtherData);
}
}
Maybe this is the best option, as it is the most efficient, but I worry that there is a chance the connection may drop between updating the Database, and sending the WebSocket notification, which may create a need for a fallback check in the PHP file, much like the one in the first solution, albeit at a longer interval (Say every 30 seconds).
3. MySQL Trigger?
This is purely a guess, but perhaps another option is to create a MySQL trigger, which can somehow notify the server.php file directly? I've no idea how this would work, and would hazard a guess that this may end up with the same or similar Query requirements as solution #1, but it's just a though...
Thank you in advance for your help :)
EDIT: Solution possibility 4
Another thought has just popped into my head in fact, whereby the PHP file used to update the database could in fact have a WebSocket message built into it. So that when the PHP file updates the database, the WebSocket server is notified via PHP, is this possible?
If you use websockets, you should use notifications from client. That's one of their main use cases.
If you're worried about inconsistencies due to connection dropping or something changing in-between, you could implement a system similar to HTTP ETags, where client would send a hash code that you can respond on server side if there is a conflict in updating.
Update: I guess I understood your initial issue a bit wrong. If I understand your use case correctly: you are sending database updates from a client and after that all connected clients need to be updated. In that case, I think server should send the update messages after DB updates have been done, so I agree with solution 4. I am assuming here that your websocket server is the same server running PHP and doing the DB updates.
However, depending on your use case, client should still send a hash value on the next request identifying its "view of the world", so you would not be doing identical updates multiple times if a connection gets broken.
Update 2: so it was now understood that you indeed use a separate, standalone websocket server. Basically you have two different web servers on the server side and are having an issue on how to communicate between the two. This is a real issue, and I'd recommend only using one server at a time - either take a look at using Apache websocket support (experimental and not really recommended) or migrating your php scripts to the websocket instance.
Neither PHP or Apache was really build with websockets in mind. It is quite easy to set up a standalone websocket server using only PHP, but it might not be so easy then to migrate the rest of the PHP stack to it if the code is relying on Apache/web server on. Apache websocket support also is hardly optimal. For a real websocket solution, unfortunately, best practice would be using a technology that is built for it from the ground up.
The better answer is to send notification through Server side when database is updated by PHP script, so that script have to add options of web sockets to directly send notification to all web socket clients registered.
User send content->Php script process content and save data according to true condition->check database is updated by checking return of mysql_query/other alternative->if true than use web-socket and send notification to all users
now this is more easy/handy/bandwidth saver.