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

万象初新
3060 3 1
3个回答

phpcreeper

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来监控设备下线,例如上面的例子

  • 万象初新 2020-07-31

    监听多个设备 用thinkphp的类方法写,有例子吗?

  • walkor 2020-07-31

    参考上面例子写就行了

  • 万象初新 2020-07-31

    @1:大佬,您能帮助我写个tp5的方式吗.我想了半天不知道该怎么弄.....

  • 万象初新 2020-07-31

    @1:下面的例子是我写的,您能看着帮我修改一下吗

  • walkor 2020-07-31

    不会tp

万象初新
<?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));
    }
}
  • 暂无评论
年代过于久远,无法发表回答
×
🔝