能否外部调用某一个进程(connect)向与workerman建立长链接的客户端发送数据

fourswall

我现在做一个项目,客户端已经链接上了,并且能发送数据,但是要接受数据返回只是在发送数据后可以接受。我发现客户端建立的是一个长链接,那是否可以我PHP程序这边外部调用一个方法,向已知workerID和connectID的连接发送数据过去呢?

4484 3 0
3个回答

walkor

如果是多进程Worker
可以使用Chnnel组件,完成进程间/服务器集群通讯。
Chnnel组件可以方便的做到进程间通讯,非阻塞IO,基于订阅发布模式
Channel组件地址:https://github.com/walkor/Channel

测试代码如下
start.php

<?php
use Workerman\Worker;
use Workerman\Connection\AsyncTcpConnection;
use Workerman\Connection\Connection;
require_once './Workerman/Autoloader.php';
require_once './Channel/src/Server.php';
require_once './Channel/src/Client.php';

// 初始化一个Channel服务端
$channel_server = new Channel\Server('0.0.0.0', 2206);

// websocket服务端
$worker = new Worker('websocket://0.0.0.0:4236');
$worker->count=2;

// 进程启动后连接Channel服务端
$worker->onWorkerStart = function($worker)
{
    // Channel客户端连接到Channel服务端
    Channel\Client::connect('127.0.0.1', 2206);
    // 当前进程订阅workerID的消息
    Channel\Client::subscribe($worker->id);
    // 当前workerID有消息时触发的回调
    Channel\Client::$onMessage = function($channel, $data)use($worker){
        $to_connection_id = $data;
        $message = $data;
        if(!isset($worker->connections))
        {
            echo "connection not exsits\n";
            return;
        }
        // 向客户端推送数据
        $to_connection = $worker->connections;
        $to_connection->send($message);
    };
};

// 客户端连接上来时打印发送当前workerID和connectionID
$worker->onConnect = function($connection)use($worker)
{
    $msg = "workerID:{$worker->id} connectionID:{$connection->id} connected\n";
    echo $msg;
    $connection->send($msg);
};

/*
 * 用来处理http请求,通过http请求向任意客户端推送数据,需要传to_worker_id和to_connection_id
 * url类似http://127.0.0.1:4237/?to_connection_id=3&to_worker_id=1&content=hello
 */
$http_worker = new Worker('http://0.0.0.0:4237');
// 进程启动后连接channel服务端
$http_worker->onWorkerStart = function()
{
    Channel\Client::connect('127.0.0.1', 2206);
};
// 收到http请求时向对应worker_id的订阅者发布消息
$http_worker->onMessage = function($connection, $data)
{
    $connection->send('ok');
    if(empty($_GET)) return;
    $to_worker_id = $_GET;
    $to_connection_id = $_GET;
    $content = $_GET;
    Channel\Client::publish($to_worker_id, array(
       'to_connection_id' => $to_connection_id,
       'content'          => $content
    ));
};

Worker::runAll();

如果是单进程Worker
可以参考手册
http://doc.workerman.net/faq/send-data-to-client.html

  • 暂无评论
詹少

这个例子我看过 但是如果是管理后台向指定用户发送消息怎么办 无法获取用户的worker_id呀

  • 暂无评论
walkor

参考这个
http://doc.workerman.net/346075
send_to_group 和 send_to_uid 实现方式是一样的

  • 暂无评论
年代过于久远,无法发表回答
🔝