📜 ⬆️ ⬇️

Implementing a daemon and its interaction with a PHP application

Actually it is rather a semi-semi-half-question.
I will describe the scheme that I got and ask the habra people for advice - how much such an implementation has the right to life and what should be improved in it =)
Perhaps someone will like this idea and he will take it into service - I do not mind =)

This scheme is used in two tasks for me, but I will sign it all with one example.
So, I have some online browser game project. The task was to write the fastest chat with the following properties:
- low load generated by chat on the server;
- support a large number of players;
- the ability to work both in continuous and in normal (refresh) modes;
- the ability of players to work for proxy servers.


')
General scheme of work


I decided to separate the processing of the message queue into a separate process - the chat chat.
The client also works with either a php script (in the case of a refresh mode) or a CGI application written in C (for continuous mode).
In both cases, messages are received from the daemon and the client is sent a JS code that adds messages to the chat frame.
In refresh-mode, the request to this php-script leaves every few seconds, the script downloads all messages that appeared after the last refresh and gives it to the client.
In continuous mode, the CGI process starts, and in an infinite loop with a slight delay checks the message queue for new ones. If they appear, they immediately send them to the client.

Demon and Client Interface


For a CGI application, the optimal version of the shared memory segment seemed to be the best.
The daemon, at startup, allocates a segment of shared memory and writes all the messages there.
The structure that describes the message has a fixed size and a simple binary format. Therefore, getting a message by its serial number in the queue is a simple task.
The message queue is cyclical, after the queue is full - new messages begin to fill the queue first, overwriting the old messages. Also in this segment are present at fixed offsets two values, showing the current indicators of the beginning and end of the queue.
The CGI client connects this memory segment at startup and obviously reads data from there, almost instantly learning about new messages.
A race condition does not arise at that; Only a demon writes to a segment. Readers can be an unlimited number.

Adding messages to the queue


To add messages to the queue, client scripts connect via a UNIX socket to the daemon and send a specially crafted data packet.

The daemon creates several threads at startup and starts listening to the socket.
Incoming connections are distributed to threads in turn.
Threads take a command from the socket. If this is a command to add a message to a queue, they capture the mutex that controls the access to the message queue, and add it there.

Pros of implementation


The problem is solved =)
Chat does not use non-standard ports - everything works through a web server, so chat can work behind hard corporate proxies.
The load on the server from the chat is almost imperceptible.

Implementation minuses


Poor scalability, the expectation that the web server and the daemon run on the same machine.

Conclusion


This scheme of work run-in on the production and did not cause comments.
However, perhaps it is not optimal - this is the best of what came to mind =)
I will be glad to hear your comments on this implementation.
If suddenly my implementation seems interesting to someone, I’m ready to talk about something in more detail, for example, to go deeper into the application part of the chat (channels, filter, message formatting, commands) or into the system part of the server implementation (with code examples).

Source: https://habr.com/ru/post/75944/


All Articles