• 2
  • 新人请关照

swoole_http_client往swoole_websocket_server 推送消息接收不到,也不报错

websocket 监听10001端口,client 是在本机,往10001端口推送 。

如果不开ssl可以推成功,开启ssl后推不成功。也不报错。请问是什么原因?

ssl证书没问题,wss可以连上websocket

服务端代码如下

$server_set = [
    //    'reactor_num' => 2, //reactor thread num
    //    'worker_num' => 4,    //worker process num
    //    'backlog' => 128,   //listen backlog
    //    'max_request' => 50,
    //    'dispatch_mode' => 1,
    'log_file'  => SOCKET_LOG_FILE,
    'daemonize' => 1, //后台运行
];

/** 获取Swoole配置 */
//如果需要 ssl的话 需要添加证书
$server = new \swoole_websocket_server('0.0.0.0', 10001, SWOOLE_PROCESS, SWOOLE_SOCK_TCP | SWOOLE_SSL);//SWOOLE_SSL  需要ssl才加
$server_set['ssl_cert_file'] = SSL_CERT_FILE_PATH;
$server_set['ssl_key_file'] = SSL_KEY_FILE_PATH;

$server->set($server_set);

$server->on('open', function(\swoole_websocket_server $server, $request) {
    echo "\r\n客户端{$request->fd}已连接";
});

$server->on('message', function(\swoole_websocket_server $server, $frame) {
    var_dump($frame);
});

//监听客户端退出登录状态
$server->on('close', function(\swoole_websocket_server $server, $fd) {
    echo "\r\n {$fd}已退出";
});

$server->start();

客户端代码如下

//直接把数据转发到ws处理
$client = new \swoole_http_client('127.0.0.1', 10001, true);

echo "\r\n 返回码";
var_dump($client->statusCode);

$client->on('message', function($client, $frame) {
    echo "\r\n 返回值";
    var_dump($frame->data);
});

$client->upgrade('/', function($client) use ($data) {
    //发送json消息
    $res = $client->push($data);
    usleep(1000);
    $client->close();
});


阅读 1.1k
评论
    3 个回答
    • 2
    • 新人请关照

    参考swoole一些衍生框架找到了一些思路,虽然没有解决根本问题,但也算是曲线救国吧。

    内部通信不使用ssl,对外连接使用Nginx反向代理解决wss问题。

    以下来自EasySwoole官方文档(根据自身情况有略微改动)

    即客户端通过wss协议连接 Nginx 然后 Nginx 通过ws协议和server通讯。 也就是说Nginx负责通讯加解密,Nginx到server是明文的,swoole不用开启ssl,而且还能隐藏服务器端口和负载均衡(何乐不为)。
    server {
    
        # 下面这个部分和你https的配置没有什么区别,如果你是 宝塔 或者是 oneinstack 这里用生成的也是没有任何问题的
        listen 10001; #对外使用wss连接的端口 (这里我有改动,视自身实际情况而定)
        server_name 这里是你申请的域名; #域名
    
        ssl on;
    
        # 这里是你申请域名对应的证书(一定要注意路径的问题,建议绝对路径)
        ssl_certificate 你的证书.crt;
        ssl_certificate_key 你的密匙.key;
    
        ssl_session_timeout 5m;
        ssl_session_cache shared:SSL:10m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv2 SSLv3;
        ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
        ssl_prefer_server_ciphers on;
        ssl_verify_client off;
    
        # 下面这个部分其实就是反向代理 如果你是 宝塔 或者是 oneinstack 请把你后续检查.php相关的 和重写index.php的部分删除
        location / {
            proxy_redirect off;
            proxy_pass http://127.0.0.1:9501;      # 转发到你本地的9501端口 这里要根据你的业务情况填写 谢谢
            proxy_set_header Host $host;
            proxy_set_header X-Real_IP $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;   # 升级协议头
            proxy_set_header Connection upgrade;
        }
    }

    重启nginx 如果没有错误 点我打开ws调试工具;

    服务地址输入wss://你上面的域名:加端口号(我这里是10001)

    点击开启连接 恭喜你 wss成了

    参考链接 EasySwoole

      示例供参考

      ProcessManager为SwooleProcess实现的进程管理类

      $count = 0;
      $pm = new ProcessManager;
      $pm->parentFunc = function (int $pid) use ($pm, &$count) {
          for ($c = MAX_CONCURRENCY; $c--;) {
              go(function () use ($pm, &$count) {
                  global $count;
                  $cli = new \Swoole\Coroutine\Http\Client('127.0.0.1', $pm->getFreePort());
                  $cli->set(['timeout' => 5]);
                  $ret = $cli->upgrade('/');
                  assert($ret);
                  $data = sha1(openssl_random_pseudo_bytes(mt_rand(0, 1024)));
                  for ($n = MAX_REQUESTS; $n--;) {
                      $cli->push($data);
                      $ret = $cli->recv();
                      assert($ret->data === "Hello {$data}!");
                      $ret = $cli->recv();
                      assert($ret->data === "How are you, {$data}?");
                      $count++;
                  }
              });
          }
          swoole_event_wait();
          assert($count === (MAX_CONCURRENCY * MAX_REQUESTS));
          $pm->kill();
      };
      $pm->childFunc = function () use ($pm) {
          $serv = new swoole_websocket_server('127.0.0.1', $pm->getFreePort(), SERVER_MODE_RANDOM);
          $serv->set([
              // 'worker_num' => 1,
              'log_file' => '/dev/null'
          ]);
          $serv->on('workerStart', function () use ($pm) {
              $pm->wakeup();
          });
          $serv->on('message', function (swoole_websocket_server $server, swoole_websocket_frame $frame) {
              $server->push($frame->fd, "Hello {$frame->data}!");
              $server->push($frame->fd, "How are you, {$frame->data}?");
          });
          $serv->start();
      };
      $pm->childFirst();
      $pm->run();
        • 1
        • 新人请关照

        楼主解决没有????

        $client = new swoole_client(SWOOLE_SOCK_TCP);
        if (!$client->connect('127.0.0.1', 9501, -1))
        {
            exit("connect failed. Error: {$client->errCode}\n");
        }
        fwrite(STDOUT, '请输入信息:');
        $msg = trim(fgets(STDIN));
        if ($client->reuse) {
            $client->send($msg);
        }else{
            $client->doHandShake();
            $client->send($msg);
        }
        $client->send($msg);
        echo $client->recv();
        $client->close();

        报错
        PHP Fatal error: Uncaught Error: Call to undefined method SwooleClient::doHandShake()

        该答案已被忽略,原因:

          撰写回答

          登录后参与交流、获取后续更新提醒