1

I am confused here on how real time analytics is accomplished with web sockets when data is inserted into the system via a REST API. In my (admitted immature) understanding of web sockets, you have many clients connected to the socket server and the socket server emits events to the connected clients. The only communication is between that socket server and those clients. What I can't figure out is how web sockets can "detect" that something in the database was updated, if that database was updated at:

https://mydomain.com/api/v1/path/here/

and the socket server is here:

https://mydomain.com/socket:9999

I can really only come up with one of two ways that this will work, and I know both are wrong:

  1. ALL API endpoints are changed to https://mydomain.com/socket:9999 AND THEN AFTER the clients are updated with the info, the socket server makes an API call to the correct place with the correct info.
  2. AFTER the API does its thing at: https://mydomain.com/api/v1/path/here/, it makes a short-lived call to https://mydomain.com/socket:9999 and updates the client data as needed, and then closes the connection.

AGAIN, I know both of these solutions are BAD, BAD solutions (they're not clean at all, they lend to writing bad code, they're incredibly brittle, not fault-tolerant, not performant, etc...), but I can't figure out another solution.

What am I missing here that allows the web socket server to update the client when data changes in the database?

I am running our REST API on PHP and the web socket server on Node.JS

  • I'm not clear on what connecting to https://mydomain.com/socket:9999 does. Is that a port that you send messages to that then get distributed to the clients? – JimmyJames Mar 13 at 17:01
  • @JimmyJames correct – Adam McGurk Mar 13 at 17:02
  • You can maintain an open websocket from the API endpoint server(s) to the websocket server, and fire off events as they happen (asynchronously) . This may depend on what platform you are using, which you don't mention. With Node and Go it wouldn't be a problem. With PHP, it probably would be. – GrandmasterB Mar 13 at 17:02
  • @GrandmasterB updated the post to include the languages. The REST API is written in PHP and the web socket server is written in Node.JS – Adam McGurk Mar 13 at 17:13
  • @AdamMcGurk With PHP your best bet is probably either approach #2, which there is nothing 'bad' about, or post something to a queue (redis, etc) watched by your websocket server like Milan mentions below in his answer. – GrandmasterB Mar 13 at 17:25
3

I'd say the 2nd solution is feasible, but, in any event, an event needs to be sent to the WS server which would broadcast a message to all clients connected. In an ideal world, I'd say a stream/message queue in between the WS Server and API would be a good way to handle passing events between those services, which would aid in creating a more message-driven architecture if you're into that kind of stuff. So the architecture would be something along the lines of:

(API SERVER) ----> (message queue/streaming platform) ---> (WS SERVER) ----> (n clients)

Where the API server receives a request, adds stuff to the database, places a message to the streaming platform/queue. The WS server pulls messages from the streaming platform (say that it's a pull-based platform like Kafka), and, on each message(event), sends a message to all clients via WebSocket communication.

There's really no ideal way of handling this, but the architecture that you currently have in place seems to be OK for creating a microservice architecture which is message-driven, you can even stretch it to a full-blown Reactive architecture ideally.

You could technically also have a service that would check the database for changes (via CHECKSUM) or something alike and then, again, notify the WS server to broadcast to clients, but, as you already have a REST API, I'd say go with the given approach.

EDIT: For more clarity around Kafka, I'd say that Robert's answer suffices, but to elaborate: Kafka is just my preference so that's what I've opted for including in the answer, it will come at an overhead of having to provide additional resources for it (and Zookeper), but it's the perfect fit for cases such as this. I've built numerous systems revolving around Kafka as you can simply knit services onto it and establish flows of data between services through topics (in a persistent and distributed way!). Anyways, I feel like we're diverging from the original question, you can read about it on their official site.

  • I was afraid that that was gonna be the answer ("there's really no ideal way of handling this"), here is my follow up question to that well explained answer: what is the point of a service like Kafka if I can just update the websockets server myself? – Adam McGurk Mar 13 at 16:44
  • 1
    Kafka provides a wealth of services and robustness over just using a simple socket. – Robert Harvey Mar 13 at 18:28
  • @AdamMcGurk Added more info even though Robert's answer really sums it up. – Milan Velebit Mar 13 at 19:58
1

I think you need to step back and clarify what your goals and requirements are here. The big question is: how crucial is it that each client be updated? Can the transaction be completed even if all clients are not notified? If the answer is no, I don't think websockets are going to work for you. In fact you are going to need a completely different kind of architecture. This is not an easy problem to solve. See the CAP Theorem.

If this is not the issue then the question becomes: do all the clients need to be informed of every change eventually or is it OK if clients to miss messages if they are offline or there's some sort of hiccup. If it's the latter, then websockets is adequate. I get the feeling that this is not the case.

If you want to make sure clients get each message (within reason), a pub-sub model like Kafka is probably a good solution. Whether you want to use websockets as a delivery system is up to you. You'd probably want to provide an additional GET API that allows clients to catch up on messages they have missed. Websocket connections are not terribly reliable and don't (by themselves) support a subscription-like model.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.