Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
terremoth opened this issue Apr 22, 2023 · 3 comments

Comments

@terremoth
Copy link

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).

@programarivm
Copy link

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.

@terremoth
Copy link
Author

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.

@programarivm
Copy link

programarivm commented Sep 16, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants