workerman同一个端口如何监听多个硬件设备在线状态

0
1596159352(1).jpg
已邀请:

blogdaren - 常年游走于 Linux、PHP、C、VIM 之间【http://www.phpcreeper.com】

赞同来自:

isset($connection->worker->connections[$connection->id])判断下

walkor

赞同来自:

<?php
use Workerman\Worker;
require_once './../Workerman/Autoloader.php';

// 初始化一个worker容器,监听1234端口
global $worker;
$worker = new Worker('tcp://0.0.0.0:1235');
// 这里进程数必须设置为1
$worker->count = 1;
// 新增加一个属性,用来保存设备id到connection的映射
$worker->deviceIdConnections = array();
// 当有设备发来消息时执行的回调函数
$worker->onMessage = function($connection, $data)use($worker)
{
// 判断当前设备是否已经验证,既是否设置了device_id
if(!isset($connection->device_id))
{
// 没验证的话把第一个包当做device_id(这里为了方便演示,没做真正的验证)
$device_id = $data;
$connection->device_id = $device_id;
/* 保存device_id到connection的映射,这样可以方便的通过device_id查找connection,
* 实现针对特定device_id推送数据
*/
$old_connection = isset($worker->deviceIdConnections[$device_id]) ? $worker->deviceIdConnections[$device_id] : null;
$worker->deviceIdConnections[$device_id] = $connection;
if ($old_connection) {
$old_connection->close();
} else {
// ====设备上线====
echo "$device_id 上线\n";
}

return;
}
};

// 当有设备连接断开时
$worker->onClose = function($connection)use($worker)
{
global $worker;
if (!isset($connection->device_id) || !isset($worker->deviceIdConnections[$connection->device_id])) {
return;
}
$device_id = $connection->device_id;
$connection_online = $worker->deviceIdConnections[$device_id];
// 连接断开时删除映射
if ($connection->id == $connection_online->id) {
unset($worker->deviceIdConnections[$device_id]);
// === 设备下线 ===
echo "$device_id 下线\n";
}

};

// 启动
Worker::runAll();

workerman里利用onClose来监控设备下线,例如上面的例子

万象初新

赞同来自:

<?php

namespace app\push\controller;

use think\Db;
use think\worker\Server;
use Workerman\Lib\Timer;

// 心跳间隔55秒
define('HEARTBEAT_TIME', 3);

class Worker extends Server
{

protected $socket = 'http://0.0.0.0:1235';

/**
* 收到信息
* @param $connection
* @param $data
*/
public function onMessage($connection, $data)
{
// dump($connection);
$post = $data['request'];
dump($post['Data']['DeviceInfo']['DeviceUUID']);
switch ($post['Name']) {
case 'heartbeatRequest':
$return = array(
'Name' => 'heartbeatResponse',
'TimeStamp' => time(),
"Code" => 1,
"Message" => ""
);

$uuid = $post['Data']['DeviceInfo']['DeviceUUID'];
$connection->worker->name = $uuid;
$this->updateDeviceStatus($uuid, 1);
return $return;
break;
case 'captureInfoRequest':
echo 1;
break;
case 'resultRequest':
echo 3;
break;
}
}

/**
* 当连接建立时触发的回调函数
* @param $connection
*/
public function onConnect($connection)
{

}

/**
* 当连接断开时触发的回调函数
* @param $connection
*/
public function onClose($connection)
{
// dump($connection->worker);
$uuid = $connection->worker->name;
// dump($uuid);
$this->updateDeviceStatus($uuid, 0);
}

/**
* 当客户端的连接上发生错误时触发
* @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(1, function () use ($worker) {
$time_now = time();
foreach ($worker->connections as $connection) {
echo "在线";
// 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间
if (empty($connection->lastMessageTime)) {
$connection->lastMessageTime = $time_now;
continue;
}
// 上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接
if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
echo "下线";
$connection->close();
}
}
});
}

/**
* note: 更改设备状态
* user: 万象初新
* date: 2020/7/28 10:04
*/
public function updateDeviceStatus($uuid, $status = 0)
{
return Db::name('julong_device')->where('uuid', $uuid)->update(array('is_online' => $status));
}
}

要回复问题请先登录注册