javascript - How to make an instant messenger without spamming the database

I am currently working on an instant messaging system. But, I have a problem with the optimization. Here is my current code:

<script>
   setInterval('load_messages()', 500);
   function load_messages(){
       $('#messages').load('loadMessages.php');
   }
</script>

Apart from the fact that, it is better to use an AJAX request to ask only for messages after a defined timestamp. Is there a way to pass a packet from the sender's page to the receiver to refresh to avoid spamming the database. Here is a schema explaining what I would like to do: enter image description here Is there a way in php, apache or javascript to do this?

Thanks for reading

Answer

Solution:

The technique you use is called short-polling. It's basically spamming the server until the server has something new to show you. Looks something like:

Client: cookie?
Server: no
Client: cookie?
Server: no
Client: cookie?
Server: no
Client: cookie?
Server: yes; here's the cookie: ????
Client: cookie?
Server: no
...

This is really inefficient, as you understood yourself; I don't know of any websites that still use short-polling.

You have other options. The easiest one (given you are using PHP) is long polling. Basically, you send a request, and the server just stalls the request, and once a new message comes the server sends the response back. This allows you to get messages immediately and not send so many messages:

Client: tell me when you have a cookie...
[loads for 1m 32s]
Server: the cookie has come [sends response]
Client: tell me when you have a cookie...
...

However, Apache handles concurrent requests by creating a new thread per request. So if you have 2 users in your chat, that's fine. But let's say you have many rooms and a total of 100,000 users long-polling your server. Your server probably can't handle that many threads and will crash. (NodeJS is very popular for realtime applications for its event-driven architecture and built-in asynchronism.)


But there are other much, better, options:

  1. Websockets: this is basically a persistent (that is until the connection is manually closed) connection between the client and server, so the client doesn't have to bug the server so much. Whenever the server has a message, it sends it to the client immediately and vice versa. Here's a good article. This is the most popular solution to realtime apps, and implemented by most chat apps like Discord or Slack.
  2. SSE (server sent events): basically, instead of the client asking the server for data, the server can send data to the client. Here's another article if you want to know how it works.

Your context: SSE is quite easy to implement in PHP without extra libraries; here's an example. Websockets, on the other hand, are a bit more complex to set up (may require a third-party library like rachet), but because of how well it works that's probably what I would consider.

Your question: Is there a way to pass a packet from the sender's page to the receiver to refresh to avoid spamming the database? If I were to exactly answer your question, SSE.

Source