When you create your first socket server you will quickly realise that one thread is not enough. In a single thread architecture a server can’t handle more then one connection at the time. It’s undesired because in most cases there will be simultaneous connections.
There are few different ways to create a multi threaded socket server in PHP. The one I’m going to show is with use of pcntl_fork(). The idea is to fork the application on every new connection. Fork creates a new child process to handle the client while parent process can go back to listening for a new connection. Just to be clear, fork creates a new process not a thread therefore title of this post should be “multi processed socket server” (as it was pointed out to me by @Zipleen).
When fork creates a child process it duplicates parent’s memory for the child. Each process has own memory scope so changing variable in one won’t affect the others (it’s almost true). When fork duplicates a PHP resource (socket connection is a resource) it only copies a reference to the same place. If two (or more) processes try to use the same resource at the same time unexpected results might occur. It’s not recommended.
In the example I’m going to show it shouldn’t be a problem. Each process will operate on one resource only.
There is one more thing to remember. Use fork only in a CLI application. Forks are not designed to work on a web server.
I’ve created an example which can be downloaded from GitHub.
From different terminals
If you will look into server.php you will find:
By default SocketServer listens on port 4444 but it can be changed with an argument:
Create socket resource.
Every connection will be handled by onConnect function. It can be found at the beginning of server.php.
Listen for clients.
Fork is called at the beginning of onConnect().
When pcntl_fork() is called application splits into two simultaneous processes. We want child to handle the connection and parent to return from the function. In order to do that we need to know which is which. In fork manual (http://php.net/manual/en/function.pcntl-fork.php) you can find that parent process will get child’s PID while for child pcntl_fork() will return 0.
Rest of the function it’s just a simple code to allow some interaction.
This is how to handle multiple connections from a CLI script. In next post I’m going to show how to communicate between processes to create a simple chat server.