Workerman 多进程集群推送 在添加onWorkerStart回调后 无法使用Channel全局广播

发布于 2022-09-11 16:41:15 字数 4657 浏览 19 评论 0

客户端发消息,无法全局广播但可以对当前用户
如果我注释 onWorkerStart 那就是可以全局广播
如果我不注释 onWorkerStart 那就不能全局广播但可以回复当前客户端
clipboard.png

clipboard.png
onWorkerStart 中只有一句输出也是不行的
下面是报错

clipboard.png
有没有大神指点一下

问题补充
文件目录

clipboard.png

文件的所有代码

<?php
//tcp_l.php
use Workerman\Worker;
require_once __DIR__ . '/Workerman/Autoloader.php';
require_once __DIR__ . '/Workerman/Lib/Timer.php';
require_once __DIR__ . '/Channel/src/Server.php';
require_once __DIR__ . '/Channel/src/Client.php';
define('HEARTBEAT_TIME', 30); // 心跳间隔30秒
define('CHECK_HEARTBEAT_TIME', 1); // 连接间隔时间

// 初始化一个Channel服务端
$channel_server = new Channel\Server('0.0.0.0', 2206);
// websocket服务端
$worker = new Worker('websocket://0.0.0.0:4236');
$worker->count=2;
$worker->name = 'pusher';
$worker->onWorkerStart = function($worker)
{
    // Channel客户端连接到Channel服务端
    Channel\Client::connect('127.0.0.1', 2206);
    // 以自己的进程id为事件名称
    $event_name = $worker->id;
    // 订阅worker->id事件并注册事件处理函数
    Channel\Client::on($event_name, function($event_data)use($worker){
        $to_connection_id = $event_data['to_connection_id'];
        $message = $event_data['content'];
        if(!isset($worker->connections[$to_connection_id]))
        {
            echo "connection not exists\n";
            return;
        }
        $to_connection = $worker->connections[$to_connection_id];
        $to_connection->send($message);
    });

    // 订阅广播事件
    $event_name = '广播';
    // 收到广播事件后向当前进程内所有客户端连接发送广播数据
    Channel\Client::on($event_name, function($event_data)use($worker){
        $message = $event_data['content'];
        foreach($worker->connections as $connection)
        {
            $connection->send($message);
        }
    });
};

//用户连接
$worker->onConnect = function($connection)use($worker)
{
    //判断来源
    //$msg = "workerID:{$worker->id} connectionID:{$connection->id} connected\n";
    $connection->send("Hello,Word!");
};
//接收消息
$worker->onMessage = function($connection, $data) {
    // 给connection临时设置一个lastMessageTime属性,用来记录上次收到消息的时间
    $connection->lastMessageTime = time();
    //显示数据
    //向客户端回发数据
    //全局广播执行报错
    $event_name = '广播';
    $content = "you just received:".$data;
    Channel\Client::publish($event_name, array(
        'content'          => $content
    ));
    //回复当前客户端正常
    //$connection->send("you just send: $data");
};
//断开链接
$worker->onClose = function ($connection){

//    foreach($text_worker->connections as $conn)
//    {
//        //$conn->send("user[{$connection->uid}] logout");
//    }
};
// 进程启动后设置一个每秒运行一次的定时器
$worker->onWorkerStart = function($worker) {
    echo "Worker starting...\n";
//    Workerman\Lib\Timer::add(CHECK_HEARTBEAT_TIME,function()use($worker){
//        $time_now = time();
//        foreach($worker->connections as $connection) {
//            // 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间
//            if (empty($connection->lastMessageTime)) {
//                $connection->lastMessageTime = $time_now;
//                continue;
//            }
//            // 上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接
//            if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {
//                $connection->close();
//            }
//        }
//    });
};

// 用来处理http请求,向任意客户端推送数据,需要传workerID和connectionID
$http_worker = new Worker('http://0.0.0.0:4237');
$http_worker->name = 'publisher';
$http_worker->onWorkerStart = function()
{
    Channel\Client::connect('127.0.0.1', 2206);
};
$http_worker->onMessage = function($connection, $data)
{
    $connection->send('ok');
    if(empty($_GET['content'])) return;
    // 是向某个worker进程中某个连接推送数据
    if(isset($_GET['to_worker_id']) && isset($_GET['to_connection_id']))
    {
        $event_name = $_GET['to_worker_id'];
        $to_connection_id = $_GET['to_connection_id'];
        $content = $_GET['content'];
        Channel\Client::publish($event_name, array(
            'to_connection_id' => $to_connection_id,
            'content'          => $content
        ));
    }
    // 是全局广播数据
    else
    {
        $event_name = '广播';
        $content = $_GET['content'];
        Channel\Client::publish($event_name, array(
            'content'          => $content
        ));
    }
};
Worker::runAll();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小矜持 2022-09-18 16:41:15

你似乎用错方式了,为什么要用Channel。
再说,如果用Channel的话,你Client::publish()事件,但你上面没提到Client::on()

蒲公英的约定 2022-09-18 16:41:15

workerman有视频教程,挺不错的。网址: https://study.163.com/course/...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文