----------------------- 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服務(wù)
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" => '您已經(jīng)綁定過了']));
}
} elseif ($arr->type === 'msg') {
// 指定UID發(fā)送消息
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推送數(shù)據(jù)
* @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 當(dāng)此用戶在次鏈接時把所有消息在發(fā)送回去,并更新type字段為1
}else{
//TODO 當(dāng)前發(fā)送用戶沒有綁定
}
}
/**
* 當(dāng)連接建立時觸發(fā)的回調(diào)函數(shù)
* @param $connection
*/
public function onConnect($connection)
{
}
/**
* 當(dāng)連接斷開時觸發(fā)的回調(diào)函數(shù)
* @param $connection
*/
public function onClose($connection)
{
if(isset($connection->uid))
{
// 連接斷開時刪除映射
unset($this->uidConnections[$connection->uid]);
}
}
/**
* 當(dāng)客戶端的連接上發(fā)生錯誤時觸發(fā)
* @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設(shè)置為當(dāng)前時間
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// 上次通訊時間間隔大于心跳間隔,則認為客戶端已經(jīng)下線,關(guān)閉連接
if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
//對下線的用戶進行添加
echo ($connection->uid."已經(jīng)離線".PHP_EOL);
$connection->close();
}
}
});
}
}