Redis 中的订阅消息转发到 WebSocket 客户端

发布于 2021-09-22 12:24 阅读 918

WebSocketTest.php

<?php
class WebSocketTest {
    public \Swoole\WebSocket\Server $server;

    public function __construct() {
        $this->server = new Swoole\WebSocket\Server("0.0.0.0", 9502);
        $this->server->on('open', function (Swoole\WebSocket\Server $server, $request) {
            echo "server: handshake success with fd{$request->fd}\n";
        });
        $this->server->on('message', function (Swoole\WebSocket\Server $server, $frame) {
            echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
            $server->push($frame->fd, "this is server");
        });
        $this->server->on('close', function ($ser, $fd) {
            echo "client {$fd} closed\n";
        });
        $this->server->on('workerStart', function ($server, $worker_id) {
            $redis = new Swoole\Coroutine\Redis();
            $redis->connect('docker-redis', 6379);
            if ($redis->subscribe(['cctv1'])){
                while ($msg = $redis->recv()) {
                    echo json_encode($msg, JSON_UNESCAPED_UNICODE).PHP_EOL;
                    if ($msg[0] == 'message') {
                        echo 'connections:'.json_encode(iterator_to_array($server->connections, true), JSON_UNESCAPED_UNICODE).PHP_EOL;
                        foreach ($server->connections as $fd) {
                            $server->push($fd, $msg[2]);
                        }
                    }
                }
            }
        });

        $this->server->start();
    }
}

new WebSocketTest();

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <script>
      var wsServer = 'ws://localhost:9502';
      var websocket = new WebSocket(wsServer);
      websocket.onopen = function (evt) {
          console.log("Connected to WebSocket server.");
          // websocket.send('fronted..');//向服务端发消息
      };

      websocket.onclose = function (evt) {
          console.log("Disconnected");
      };

      websocket.onmessage = function (evt) {
          console.log('Retrieved data from server: ' + evt.data);
      };

      websocket.onerror = function (evt, e) {
          console.log('Error occured: ' + evt.data);
      };
  </script>
</head>
<body>

</body>
</html>

测试

开启服务
php WebSocketTest.php

浏览器访问index.html,并打开控制台

执行redis操作
redis-cli
127.0.0.1:6379> publish cctv1 haha

不出意外,浏览器控制台就会看到 haha

广而告之,我的新作品《语音助手》上架Google Play了,欢迎下载体验