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();
});


阅读 4.7k
3 个回答
✓ 已被采纳新手上路,请多包涵

参考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();
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题