Reputation: 1403
I've implemented realtime chat in Websockets and it works just like a charm. I did it side by side with AJAX polling (which existed before), as I didn't want to remove AJAX polling support for older browsers, so although Websockets will be preferred, I am keeping polling as an option.
The way I have the websocket code set up is to:
The way the AJAX send works is:
The way the AJAX poll works is:
I have more of a conceptual question about how to get the two to work with each other. Assume I have User A and User B. If User A and User B are either both using AJAX polling or both using websockets, there are no issues whatsoever. It works as you would expect. But take the case when User A is using websockets and User B is using AJAX polling.
A → B
B → A
This is what I'm hung up on. Websocket -> AJAX user messages work because the message ends up in the database where it can be polled by an AJAX user. But websocket users don't poll the database at all, so messages from AJAX users have no way of getting into the pipeline. Currently, websocket users don't see any messages from AJAX users. They only see them if they do a full page reload, at which point all messages get retrieved directly from the database.
What would be the appropriate method to allow some way for messages from AJAX users to get sent out via websocket to relevant websocket users? Basically, how can I communicate in the other direction?
The only thing I've been able to find on this subject is this slideshow - however, I'm not using longpolling, and I'm not entirely sure what it means by "providing that" to the websocket app. Does that mean put the onus on the websocket server to check for new AJAX messages? Is there no way to "push" from the AJAX script to the websocket server?
Upvotes: 1
Views: 395
Reputation: 1403
Thanks to ADyson for some ideas on how to approach this. This is what I ended up doing:
I have my JS clients ping the server every few seconds. For AJAX users, it's more frequent because they need to poll for messages. For Websocket users, they don't need to poll for websocket messages, so they poll every 15s to "check in". This has the benefit of functioning as an infinite loop essentially for each client, which is exactly what the idea requires.
What I did was essentially add a column to the messages
table that keeps track of the message source: 0
for AJAX and 1
for WebSocket. Then, I modified the function that retrieves messages to take in an $ajaxOnly
parameter. When I call this on an AJAX poll, it's false
. For websocket polls, I call it with true
instead. The result is for all rooms a user is in, it polls the DB and checks if there are any new AJAX messages. If there are, it sends them back to the client.
There are 2 caveats:
This isn't a perfect solution, but it does meet the goal of allowing AJAX messages to show up for websocket users in near-realtime. For me, I wanted to fully support AJAX and WebSocket, but AJAX is more for compatability and ideally most people will use WebSockets, so the fact that this isn't a great solution doesn't concern me too much, since it does get the job done.
If you were hoping for a realtime solution (like I was), you're going to be disappointed by this, but this is at least a workable solution so I've adopted it until something better comes up. You can make it near-realtime by increasing the frequency with which clients ping your server.
Upvotes: 1
Reputation: 203
Simple solution: When you save the message into the Datebase, push it to the Websocket Clients as well.
Upvotes: -2