服务端发消息到客户端

服务端发消息到客户端进行通讯,执行的原理为:在启动workerman时写入和客户端通讯事件。在启动后事件常驻内存。调用frame内部通讯服务来执行事件

frame协议说明:workerman定义了一种叫做frame的协议,协议格式为 总包长+包体,其中包长为4字节网络字节序的整数,包体可以是普通文本或者二进制数据

配置说明

config\workerman.php

return [
    'channel' => [
        //内部通讯监听端口
        'port' => 20012,
        //内部通讯地址
        'ip' => '127.0.0.1',
    ],
];

事件添加

crmeb\services\workerman\WorkermanService.php 文件为总平台端启动事件回调。onWorkerStart为启动workerman后的回调事件。

//启动workerman后的回调事件
public function onWorkerStart(Worker $worker)
{
        var_dump('onWorkerStart');

        ChannelService::connet();

        //增加crmeb事件
        Client::on('crmeb', function ($eventData) use ($worker) {
            if (!isset($eventData['type']) || !$eventData['type']) return;
            $ids = isset($eventData['ids']) && count($eventData['ids']) ? $eventData['ids'] : array_keys($this->user);
            foreach ($ids as $id) {
                if (isset($this->user[$id]))
                    $this->response->connection($this->user[$id])->success($eventData['type'], $eventData['data'] ?? null);
            }
        });
}

crmeb\services\workerman\chat\ChatService.php 文件为用户端启动事件回调。onWorkerStart为启动workerman后的回调事件

public function onWorkerStart(Worker $worker)
{
        ChannelService::connet();
        //增加crmeb_chat事件
        Client::on('crmeb_chat', function ($eventData) use ($worker) {
            if (!isset($eventData['type']) || !$eventData['type']) return;
            $ids = isset($eventData['ids']) && count($eventData['ids']) ? $eventData['ids'] : array_keys($this->user);
            $fun = $eventData['fun'] ?? false;
            foreach ($ids as $id) {
                if (isset($this->user[$id])) {
                    if ($fun) {
                        $this->handle->{$eventData['type']}($this->user[$id], $eventData + ['data' => []], $this->response->connection($this->user[$id]));
                    } else {
                        $this->response->connection($this->user[$id])->success($eventData['type'], $eventData['data'] ?? null);
                    }
                }
            }
        });
}

服务器端发送信息到客户端

use crmeb\services\workerman\ChannelService;

//向平台端发送消息
 ChannelService::instance()
     ->send('PAY_SMS_SUCCESS', ['price' => $price, 'number' => $num], [$attach]);


//向客户端发送消息
//PAY_SMS_SUCCESS属于消息类型,前台根据事件类型来做出对应的逻辑处理
 ChannelService::instance()
     ->setTrigger('crmeb_chat')
     ->send('PAY_SMS_SUCCESS', ['price' => $price, 'number' => $num], [$attach]);