现象描述:
服务器端通过Nginx做了代理。
客户端能通过ws协议和后端连接上,但是一直显示pending状态。客户端无法收到服务器端返回的消息,但是服务器端能收到客户端请求建立链接的消息。
此时如果客户端调用发送方法,比如 $connection->send('welcome!'); 服务器端没有异常,但是客户端收不到。
当停止workerman服务的时候,服务器端的消息反而能发送出去,此时客户端也能收到消息。
也就是说,当服务启动的状态下,服务器发出去的消息都被阻塞了,并没有发出去。请问这个问题怎么解决?
我试过单独用workerman,不使用nginx做代理,一切正常。
PHP的代码如下:
<?php
require __DIR__ . '/../../vendor/autoload.php';
use Workerman\Worker;
// 创建一个Websocket服务器
$ws_worker = new Worker("websocket://127.0.0.1:9100");
// 设置当前Worker实例启动多少个进程
$ws_worker->count = 4;
// 在新连接到来时发出
$ws_worker->onConnect = function($connection) {
$connection->send('welcome!');
echo "new connection from ip " . $connection->getRemoteIp() . "\n";
};
// 接收数据时发出
$ws_worker->onMessage = function($connection, $data) {
//echo "{$data}\n";
$connection->send('got!');
};
// 连接关闭时发出
$ws_worker->onClose = function($connection) {
echo "Connection closed\n";
};
// 运行worker
Worker::runAll();
Nginx的配置如下:
location /wss {
proxy_pass http://127.0.0.1:9100;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Real-IP $remote_addr;
}
前端请求如下:
/**
执行这行代码之后,服务器端会显示 new connection from ip 127.0.0.1
此时浏览器会显示wss的请求状态是pending。
如果在这个时候把服务器的workerman停止,浏览器会显示101状态,并且能收到服务器发送的welcome字符串
*/
let ws = new WebSocket('ws://wodeyuming/wss')
/*
如果此时调用这条,会报错:Uncaught DOMException: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.
*/
ws.send(123)
实在搞不定,暂时先把Nginx去掉了。
nginx的wss块加一行
👍🏻!确实有效
这个方法还是不太行啊。加上这行之后,只对第一次send起作用,后面再调用$connection->send,消息就发不出去了。不用Nginx的话一切正常。