TP中利用workman获取实时数据

2019-12-18 17:35:22 浏览数 (1)

TP5.1中 利用workman获取实时数据更新

最新在项目当中需要实现数据的实时更新,于是利用workman简单的实现了对数据的实时获取。

  1. 首先下载workman,可以利用composer引入也可以直接下载workman放在项目当中(这里因composer中的workman版本比较低,所以直接下载的最新版本放到的项目当中)
  2. 在application下面创建一个websocket文件夹,里面创建一个ws_start.php 用来写websocket相关的业务
  1. 编写ws_start.php ,直接上代码
代码语言:javascript复制
use WorkermanWorker;
use WorkermanLibTimer;

require_once __DIR__.'/../../Workerman/Autoloader.php';

//设置心跳时间 55秒
define('Heartbeat',55);

$ws = new Worker('websocket://0.0.0.0:8012');


// 启动2个进程对外提供服务
$ws->count = 2;

$ws->onWorkerStart = function ($ws){
    //设置一个 间隔 1秒的定时
    Timer::add(1,function ()use($ws){
        $time_now = time();
        foreach($ws->connections as $connection) {
            // 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间
            if (empty($connection->lastMessageTime)) {
                $connection->lastMessageTime = $time_now;
                continue;
            }
            // 上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接
            if ($time_now - $connection->lastMessageTime > Heartbeat) {
                $connection->close();
            }
        }
    });

};

//当客户端连接时
$ws->onConnect = function ($connection){
    echo $connection->id."connect n";
};

// 当收到客户端发来的数据后返回hello $data给客户端
$ws->onMessage = function($connection, $data)
{

    $arr = ['device_id' => $data];
    //$data = json_decode($data,true);

    $row = httpsRequest('http://xxxxxxxxxxxx/api/getData',$arr);
    // 给connection临时设置一个lastMessageTime属性,用来记录上次收到消息的时间
    $connection->lastMessageTime = time();
    // 向客户端发送hello $data
    $connection->send($row);
};

$ws->onClose = function($connection)
{
   echo $connection->id."close n";
};

//curl
function httpsRequest($url, $data=null) {
    //1.初始化会话
    $ch = curl_init();
    //2.设置URL和相应的选项
    //设置请求的url
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    //保证返回成功的结果是服务器的结果
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    if(!empty($data)) {
        //发送post请求
        curl_setopt($ch, CURLOPT_POST, 1);
        //设置发送post请求参数数据
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }
    //3.执行会话,$result 是微信服务器返回的json字符串
    $result = curl_exec($ch);
    //4.关闭cURL资源,并且释放系统资源
    curl_close($ch);
    //5.返回json数组
    return $result;
}

// 运行worker
Worker::runAll();

代码解析:首先创建进程,并设置 进程启动,客户端连接,收到客户端消息,以及断线时的回调。然后利用定时器获取客户端接收消息的最后时间,并通过这个时间来检测客户端是否掉线,然后前端把数据的id当做心跳传过来,在onMessage回调里面接收到后,通过id然后请求接口并发送curl,然后返回json并发送给客户端,这样就相当于客户端发送---服务端接收返回,比如客户端设置3秒上传心跳包,那么就相当于3秒请求,并查询返回数据,从而实现了简单的实时数据获取。但有个问题就是这边是通过curl发送的http请求,而接口是php-fpm的运行模式,所以当客户端数量较多时,请求较多时,会出现接口服务器宕机或者卡顿,请求处理不过来的情况。所以以上代码还有很大的优化空间

0 人点赞