php - swoole中的websocket的如何发给指定人消息.

查看:494
本文介绍了php - swoole中的websocket的如何发给指定人消息.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

swoole版本:1.9.2
需求: 类似直播的评论功能, 比如A房间下面显示A房间的评论 B房间下面显示B房间的评论.... 这个应该是个正常的需求吧.. 但是我现在发现一个问题, 就是 消息是发给所有在线链接者.. 就是相当于A下面的评论在 BCDEF 都能看到.. 这就很蛋疼了... 不知道啥问题.. 求各位大哥大姐帮帮忙看看. 公司很急呀

代码如下:

<?php
$ws = new Swoole\Websocket\Server("0.0.0.0", 9508);

//监听WebSocket连接打开事件
$ws->on('open', function ($ws, $request) {

    $fd = $request->fd;
    echo "client-{$fd} is connect\n";
    //$ws->push($request->fd, "hello, welcome\n");
});

//监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) {

    // $msg =  'from'.$frame->fd.":{$frame->data}\n";
    // $data   = htmlentities(htmlspecialchars($frame->data));
    // if(mb_strlen($data,'utf8')>30){
    //     $data = mb_substr($data, 0,30,'utf-8').'...';
    // }
    $data = json_decode($frame->data,true);
     //判断是否有礼物
    if($data['gift']){
        $gift = json_decode($data['gift'],true);
        $arr = array(
        'info'   => $data['info'],
        'uid'    => $data['uid'],
        'username' =>$data['username'],
        'imageSrc' =>$gift['img'],
        'number' =>$gift['number'],
    );

    }else{

    // 正常发送
    $arr = array(
        'info'   => $data['info'],
        'uid'    => $data['uid'],
        'username' =>$data['username'],
        'href'   => 'javascript:void(0);',
        'status' => 1
    );
    }

    $msg = json_encode($arr);

    foreach($ws->connections as $fd) {
        //发送信息
        $ws->push($fd, $msg);
    }


});

//监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) {
    echo "client-{$fd} is closed\n";
});

$ws->start();

解决方案

发送到指定的人,必须知道指定的人的fd,可以在用户登录的时候将uid和fd做个关联存到redis或者swoole_table等其他共享内存中,通过uid找到fd进而push到这个fd上。

你看你代码中的

foreach($ws->connections as $fd) {
        //发送信息
        $ws->push($fd, $msg);
    }

其中$ws->connections是获取所有的文件描述符,你如果要A直播间能看到A的评论,B能看到B的评论,你应该对fd进行分组,诸如使用redis将所有在A直播间下的fd保存到一个集合中。在A直播间下进行的评论,只取出A直播间下的fd.
举个例子,伪代码:

//当用户进入A直播间
$redis->sadd('RoomA', $fd);

给A直播间下的人发送消息

//获取所有属于A直播间下的用户的fd
$clients = $redis->smembers('RoomA');
foreach($clients as $key => $fd) {
    $ws->push($fd, $msg);
}

这篇关于php - swoole中的websocket的如何发给指定人消息.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆