上代码:
服务端:
class Websocket extends Command
{
protected $server;
protected function configure()
{
// setName 设置命令行名称
// setDescription 设置命令行描述
$this->setName('websocket:start')->setDescription('Start Web Socket Server!');
}
// 设置命令返回信息
protected function execute(Input $input, Output $output)
{
$this->server = new \swoole_websocket_server('0.0.0.0', 10000);
$this->server->set([
/**
* 设置启动的worker进程数
* 业务代码是全异步非阻塞的,这里设置为CPU的1-4倍最合理
* 业务代码为同步阻塞,需要根据请求响应时间和系统负载来调整
*/
'worker_num' => 4,
// 守护进程化
'daemonize' => false,
// 监听队列的长度
'backlog' => 128
]);
$this->server->on('Open', [$this, 'onOpen']);
$this->server->on('Message', [$this, 'onMessage']);
$this->server->on('Close', [$this, 'onClose']);
$this->server->on('WorkerStart', [$this, 'onWorkerStart']);
$this->server->start();
}
public function onOpen(\swoole_websocket_server $server, \swoole_http_request $request)
{
echo "server: handshake success with fd{$request->fd}\n";
}
public function onWorkerStart($server,$workerId){
echo "worker started: {$workerId}\n";
$server->tick(2000, function() use ($server) {
$workFd = Cache::get("workFd");//只通知工作客户端
if(empty($workFd)|| count($server->connections)==0)
return;
$server->push($workFd,time());
});
}
}
// 收到数据时回调函数
public function onMessage(\swoole_websocket_server $server, \swoole_websocket_frame $frame)
{
$data = $frame->data;
if($data=="workStart") {
echo "fd:".$frame->fd."is work fd";
Cache::set("workFd",$frame->fd,60*60*24);
}
$workFd = Cache::get("workFd");
if(!empty($workFd)&&$frame->fd!=$workFd){
$server->push($workFd,$frame->data);
}
}
// 连接关闭时回调函数
public function onClose($server, $fd)
{
$workFd = Cache::get("workFd");
if(!empty($workFd)&&$workFd==$fd){
Cache::rm("workFd");
}
echo "client {$fd} closed\n";
}
}
客户端js
var wsServer = 'ws://XXX.XXX.XXX.XXX:10000';
//调用websocket对象建立连接:
//参数:ws/wss(加密)://ip:port (字符串)
var websocket = new WebSocket(wsServer);
//onopen监听连接打开
websocket.onopen = function (evt) {
websocket.send("workStart");
};
//监听连接关闭
websocket.onclose = function (evt) {
console.log("Disconnected");
};
//onmessage 监听服务器数据推送
websocket.onmessage = function (evt) {
// console.log('Retrieved data from server: ' + evt.data);
};
setInterval(function () {
websocket.send(Date.parse(new Date()));
},10000);
当 'daemonize' => false,
服务端启动后,大概1个小时左右的时间内服务端和客户端的通信是正常的,之后客户端就无法在连接到服务端,
通过centos命令 查看服务端的进程是存在的,只能通过kill的方式杀掉服务,并重启,客户端又可以连接到服务端
当 'daemonize' => ture,
服务端启动后,客户端始终无法连接到服务端
请问要怎么解决
1、更新版本
2、检查进程状态
3、检查socket连接状态(比如close_wait)
4、内核调优
...