workerman 实现不同用户推送不同消息问题

cxjphp

需求:根据client端发送的不同uid,server端推送对应uid比较感兴趣的一些话题给不同的用户

每个client 端都有唯一一个uid发送给服务端:
ws.send(JSON.stringify({"type":"attention","uid":UID}));
此时uid=416

server端发送数据的时候:
ws.send(JSON.stringify({"type":"send","uid":"416","content":input.value}));

在onMessage中处理:

switch($message_data)
{
    // 发送数据给用户 message: {type:send, to_client_id:xx, content:xx}
    case 'send':
        // 向某个浏览器窗口发送消息
        if($message_data != 'all')
        {
            $new_message = array(
                'content'=>nl2br($message_data)
            );
            Gateway::sendToUid($message_data, json_encode($new_message));
        }
        // 向所有浏览器发送消息
        $new_message = array(
            'content'=>nl2br($message_data)
        );
        return Gateway::sendToAll(json_encode($new_message));
        break;
    case 'attention':
        Gateway::bindUid($client_id,$message_data);
        break;
}

在server端发送消息的时候所有client端都收不到消息,希望来个知道的人,详细说一些或者发个实例看看,谢谢!

11030 1 0
1个回答

walkor 打赏

bindUid sendToUid 的原意是将现有系统的id 和 GatewayWorker的client_id联系起来。
例如现有的商城系统要做一个客服系统(gatewayWorker做),商城系统有自己的id体系,每个用户有一个uid,唯一标记一个用户。gatewayWorker有也有自己的id体系,也就是client_id,唯一标记一个连接。

客服要给某个商城用户发送消息,就需要知道这个用户当前的client_id是什么才能发送。
有了bindUid,将商城uid与gatewayWorker的client_id绑定,那么就可以直接调用sendToUid给商城用户发送数据了。

client_id 与 uid的绑定在Event::onMessage中做,代码类似

class Event
{
    public static function onMessage($client_id, $message)
    {
        //{"type":"attention","uid":UID}
        $message = json_decode($message, true);
        // 先判client_id是否已经绑定uid了,没绑定则执行绑定
        if(!isset($_SESSION))
        {
            Gateway::bindUid($client_id, $message);
            $_SESSION = $message;
            return;
        }

        // 其它罗辑  例如给某个用户发送消息  sendToUid($one_uid, 'xxxxx');
    }
}

分割线
——————————————————————————————————————————
其实楼主要的是订阅功能,其实不关心什么uid\client_id,
只关心谁订阅了哪个主题的消息,怎么把消息发给这些订阅者,
其实这个用bindUid就能很方便的解决。

把uid当做主题即可,把uid当做主题即可,把uid当做主题即可。
bindUid的作用就是将某个client_id与某个主题绑定,
sendToUid就是给某个主题的所有订阅者发送消息。

代码类似这样

class Event
{
    public static function onMessage($client_id, $message)
    {
        // 绑定主题的格式 {"type":"attention","subject":"话题1"}
        $message = json_decode($message, true);
        // 先判是不是绑定话题的包
        if($message == 'attention')
        {
            Gateway::bindUid($client_id, $message);
            return;
        }

        // 给某个话题的所有订阅者发送消息
        // 给主题发布消息的格式 {"type":"publish","subject":"话题1", "content":"这个是消息内容"}
        Gateway::sendToUid($message, $message);
    }
}

这个问题估计楼主也感兴趣,如何在其它系统中向uid(或者说订阅者)发消息,参见
http://doc2.workerman.net/push-in-other-project.html
使用GatewayClient,可以在任意系统中调用Gateway::sendToUid / Gateway::sendToClient发送数据,即使是其它非workerman环境的服务器

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