tcp长连接程序,里面启动了一个Text协议的内部端口程序,执行 php think start 报错,提示 内部端口 Address already in use
Worker::$pidFile = '/var/run/workerman_relay.pid';
$tcp_worker = new Worker("tcp://0.0.0.0:2347");
// 启动4个进程对外提供服务
$tcp_worker->count = 4;
//---------------------------------- onWorkerStart start ---------------------------
$tcp_worker->onWorkerStart = function($tcp_worker) {
Timer::add(10, function () use ($tcp_worker) {
$time_now = time();
foreach ($tcp_worker->connections as $connection) {
// 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// 上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接
if ($time_now - $connection->lastMessageTime > Relay::$heartbeat_time){
$connection->close();
}
}
});
// 开启一个内部端口,方便内部系统推送数据,Text协议格式 文本+换行符
$inner_text_worker = new Worker('Text://0.0.0.0:5332');
$inner_text_worker->onMessage = function ($connection, $buffer) use ($tcp_worker) {
// $data数组格式,里面有uid,表示向那个uid的页面推送数据
$data = json_decode($buffer, true);
$uid = $data['padCode'];
// 通过workerman,向uid的页面推送数据
$ret = Relay::sendMessageByUid($tcp_worker,$uid, json_encode($data['param']));
dump($data);
return $connection->send(json_encode(['padCode'=>$uid,'status'=> (bool)$ret]));
};
$inner_text_worker->listen();
};
Worker::runAll();
stream_socket_server(): unable to connect to tcp://0.0.0.0:5332 (Address already in use)
已解决
$tcp_worker->count = 4 的问题,每个进程就是一个端口启动,4个就是启动了4次端口,所以提示占用
进程数设置为1或者设置
$inner_text_worker->resuePort = true;
,reusePort作用参见手册 https://www.workerman.net/doc/workerman/worker/reuse-port.html另外如果开启多进程,进程间是完全隔离的,比如客户端1连接了A进程,客户端2连接了B进程,A进程没办法直接获取B进程的连接数据,也就是客户端1和客户端2之间没办法直接通讯。要通讯的话需要做进程间通讯,例如用channel组件等方案。如果没有多进程编程经验,建议直接开1个进程,或者用gatewayWorker。
如果workerman只做通讯,没有数据库等阻塞访问,开一个进程就可以支持几万连接,一般业务够用了。
好的,谢谢大佬