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

Create a Swoole WebSocket server that subscribes to new messages from Redis using Redis Pub/Sub. #5580

Open
AnyutaH opened this issue Nov 21, 2024 · 2 comments

Comments

@AnyutaH
Copy link

AnyutaH commented Nov 21, 2024

Hi everyone, could someone tell how to send an event from a process to server. I am creating a WebSocket server with Redis pub/sub and subscribing to a Redis channel in the WebSocket server process, but how to pass data to server?
Or is there another approach?
If I write the subscribing code in the workerStart event, the webSocket server will not accept new connections.

$this->server->on("workerStart", function ($server, $workerId) use ($redis) {
    $redis->subscribe(['chat_channel'], function ($redis, $channel, $message) {
        foreach ($this->server->connections as $fd) {
              $this->server->push($fd, json_encode($message));
        }
    });
});

I guess this is because the phpredis client is blocking, but how to write a code that will accept messages from Redis and broadcast them to connected users?

I am really struggling with this. Please help if you know how to solve it. Thank you very much!

  1. What version of Swoole are you using (show your php --ri swoole)?
php --ri swoole

swoole

Swoole => enabled
Author => Swoole Team <[email protected]>
Version => 6.0.0-dev
Built => Oct  7 2024 17:07:28
coroutine => enabled with boost asm context
epoll => enabled
eventfd => enabled
signalfd => enabled
cpu_affinity => enabled
spinlock => enabled
rwlock => enabled
http2 => enabled
json => enabled
pcre => enabled
zlib => 1.2.11
brotli => E16781312/D16781312
mutex_timedlock => enabled
pthread_barrier => enabled
futex => enabled

Directive => Local Value => Master Value
swoole.enable_library => On => On
swoole.enable_fiber_mock => Off => Off
swoole.enable_preemptive_scheduler => Off => Off
swoole.display_errors => On => On
swoole.use_shortname => On => On
swoole.unixsock_buffer_size => 8388608 => 8388608
  1. What is your machine environment used (show your uname -a & php -v & gcc -v) ?
Linux developer-v3 5.4.0-26-generic #30-Ubuntu SMP Mon Apr 20 16:58:30 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

PHP 8.3.14 (cli) (built: Nov 21 2024 05:47:02) (NTS)

@NathanFreeman
Copy link
Member

NathanFreeman commented Nov 23, 2024

You can use a custom process to do this.

$server = new Swoole\Websocket\Server('127.0.0.1', 9502, SWOOLE_PROCESS);

$process = new Swoole\Process(function() use ($server) {
    $redis->subscribe(['chat_channel'], function ($redis, $channel, $message) {
        foreach ($server->connections as $fd) {
              $server->push($fd, json_encode($message));
        }
    });
});
$server->addProcess($process);

.....
$server->start();

@AnyutaH
Copy link
Author

AnyutaH commented Nov 23, 2024

Yes, it worked with SWOOLE_PROCESS set on server, thank you very much @NathanFreeman

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