----------------------- WORKERMAN -----------------------------
Workerman version:3.5.31 PHP version:7.3.4
------------------------ WORKERS -------------------------------
worker listen processes status
none websocket://0.0.0.0:2345 1 [ok]
[think\exception\ErrorException]
Undefined property: Workerman\Connection\TcpConnection::$uid
Worker process terminated
一会就提示这个了
<?php
declare (strict_types=1);
namespace app\worker;
use Exception;
use think\worker\Server; //worker服务
use Workerman\Lib\Timer; //心跳类库
define('HEARTBEAT_TIME', 15); //心跳间隔
class Worker extends Server
{
protected $socket = 'websocket://0.0.0.0:2345'; //链接地址
protected $uidConnections = array();
/**
* 收到用户消息
* @param $connection
* @param $data
* @return bool
*/
public function onMessage($connection, $data): bool
{
$arr = json_decode($data);
if (empty($arr->type)){
$connection->send(json_encode(["code" => 202, "msg" => '1']));
return $connection->close();
}
if($arr->type === 'PING'){
$connection->lastMessageTime = time();
return $connection->send(json_encode(["type" => 'PONG']));
}
if ($arr->type === 'bind') {
if (empty($arr->uid)) return $connection->send(json_encode(["code" => 202, "msg" => '2']));
//用户UID绑定并判断是否绑定过
if (!isset($connection->uid)) {
$connection->uid = $arr->uid;
$this->uidConnections[$connection->uid] = $connection;
return $connection->send(json_encode(["code" => 200, "msg" => '链接成功', "data" => $connection->uid]));
} else {
return $connection->send(json_encode(["code" => 201, "msg" => '您已经绑定过了']));
}
} elseif ($arr->type === 'msg') {
// 指定UID发送消息
if (empty($arr->toUId) || empty($arr->content)) return $connection->send(json_encode(["code" => 202, "msg" => '3']));
$this->sendMessageByUid($arr->toUId, $arr->content);
}
return true;
}
/**
* 指定uid推送数据
* @param $uid
* @param $message
* @return void
*/
function sendMessageByUid($uid, $message)
{
if (isset($this->uidConnections[$uid])) {
$connection = $this->uidConnections[$uid];
$connection->send($message);
//TODO 判断是否在线不在线则将消息存如MySQL type状体为 0 当此用户在次链接时把所有消息在发送回去,并更新type字段为1
}else{
//TODO 当前发送用户没有绑定
}
}
/**
* 当连接建立时触发的回调函数
* @param $connection
*/
public function onConnect($connection)
{
}
/**
* 当连接断开时触发的回调函数
* @param $connection
*/
public function onClose($connection)
{
if(isset($connection->uid))
{
// 连接断开时删除映射
unset($this->uidConnections[$connection->uid]);
}
}
/**
* 当客户端的连接上发生错误时触发
* @param $connection
* @param $code
* @param $msg
*/
public function onError($connection, $code, $msg)
{
echo "error $code $msg\n";
}
/**
* 每个进程启动
* @param $worker
*/
public function onWorkerStart($worker)
{
Timer::add(10, function()use($worker){
$time_now = time();
foreach($worker->connections as $connection) {
// 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// 上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接
if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
//对下线的用户进行添加
echo ($connection->uid."已经离线".PHP_EOL);
$connection->close();
}
}
});
}
}
不要用这个去做,使用GatewayWorker 去做:https://www.workerman.net/doc/gateway-worker/principle.html
用上了 GatewayWorker 了