ratchetphp / Ratchet

Asynchronous WebSocket server

Home Page:http://socketo.me

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Newbie question: is it possible to handle thousands of connections making many channels like IRC and without using all TCP available ports?

terremoth opened this issue · comments

I was thinking in building something similar to a IRC chat, but I have no idea how I could handle many different channels without opening different PHP processes for each TCP available port (one for each channel in the list).

The idea of non-blocking I/O can be somehow tricky at first.

Ratchet is built on ReactPHP which provides non-blocking I/O operations. This allows a process to run on a port serving multiple requests at the same time without being blocked, so there is no need to use all available TCP ports for implementing an IRC chat.

In fact, well, IRC runs on 6667/TCP.

I guess it is all about the app's architecture.

The idea of non-blocking I/O can be somehow tricky at first.

Ratchet is built on ReactPHP which provides non-blocking I/O operations. This allows a process to run on a port serving multiple requests at the same time without being blocked, so there is no need to use all available TCP ports for implementing an IRC chat.

In fact, well, IRC runs on 6667/TCP.

I guess it is all about the app's architecture.

I don't understand how can I handle multiple connections in different channels using the same port. Is this possible somehow? Because every example I saw was 1 channel for 1 port.

Well, a TCP port is not the same thing as an IRC channel. A chat channel is kind of a concept that your app has to deal with.

Once comfortable with this non-blocking I/O concept, it is crucial to also understand how the connections can be stored into an object-oriented PHP socket. The simple Chat application described in the docs stores client connections in an SplObjectStorage object.

However, if you're taking your first steps with object-oriented non-blocking I/O apps, the client connections can be stored in a built-in PHP array.

See:

The simplest way to store client connections is using a one-dimensional array in the onOpen() method as per Ratchet\ComponentInterface. Now, in order to categorize those connections into different channels, you may want to add an additional attribute to the PHP socket called $this->channels.

Also, you want to define a set of commands for the clients to do a bunch of differernt things like joining a channel, leaving a channel, and so on, for which you'll need a command parser.

Examples in the context of a music application:

  • /join baroque
  • /leave baroque
  • /join jazz
  • /leave jazz

The /join jazz command can be parsed in the onMessage() method as per Ratchet\MessageInterface, and this is how to add a new entry into $this->channels.

    // ...
    
    public function onMessage(ConnectionInterface $from, $msg)
    {
        // TODO
        // Parse the '/join jazz' command in $msg to obtain a $channel

        $this->channels[$from->resourceId][] = $channel;

        // ...
    }
    
    // ...

This example will allow to handle many channels like IRC without using all TCP available ports.