登录  /  注册

作为socket长连接服务器,Swoole如果要做到主动对已经连接过来的,用户uid=123的那个用户,推送一条消息应该怎么写?

php中文网
发布: 2016-08-04 09:22:09
原创
1042人浏览过

额,这应该是菜鸟级别的问题,但是看了文档我还是无从下手。

回复内容:

额,这应该是菜鸟级别的问题,但是看了文档我还是无从下手。

php的socket是资源类型:
resource(4) of type (Socket),也就是每个socket句柄都一个样子。。

而Linux C socket fd是个int整数,每个都是不同数字。

原生php做不到“主动对已经连接过来的,用户uid=123的那个用户,推送一条消息”,
但借助Swoole利用linux C实现的socket,我们可以实现“主动对已经连接过来的,用户uid=123的那个用户,推送一条消息”。

这里我们可以用System V最简单的share memory来进程间共享数据IPC,维护一个用户id与其socket连接的映射表。

代码如下:

<code><?php $serv = new <a style='color:#f60; text-decoration:underline;' href="https://www.php.cn/zt/53189.html" target="_blank">swoole_server("127.0.0.1", 1024);
$serv-&gt;set(array(
    'worker_num' =&gt; 8,   //工作进程数量
    'daemonize' =&gt; false, //是否作为守护进程
));

$shmid = shm_attach(getmypid(), 1024*66); # allocate 66kB for shared memory
define("SHARED_UID_CONNECTION_MAP", 12);
shm_put_var($shmid,SHARED_UID_CONNECTION_MAP, []);

$serv-&gt;on('connect', function ($serv, $fd) use($shmid) {
    echo "Client:Connect.\n";
});

$serv-&gt;on('receive', function ($serv, $fd, $from_id, $data) use($shmid)  {

    $serv-&gt;send($fd, 'Swoole: '.$data);
    // $serv-&gt;close($fd);

    $trimdata = trim($data);
    if ($trimdata == 'i am lucky man') {
        $map = shm_get_var($shmid,SHARED_UID_CONNECTION_MAP);
        $map[] = $fd;   #$map[$uidFromData] = $fd;
        shm_put_var($shmid,SHARED_UID_CONNECTION_MAP, $map);
    }


    if ($trimdata == 'broadcast to lucky man') {
        $map = shm_get_var($shmid,SHARED_UID_CONNECTION_MAP);
        // var_dump($map); $ $map is array whose valuse is int $fd
        foreach($map as $fd) {
            $serv-&gt;send($fd, "some body broadcast to you luck man");
        }
    }

    # broadcast to all users
    // $start_fd = 0;
    // while(true)
    // {
    //     $conn_list = $serv-&gt;connection_list($start_fd, 10);
    //     if($conn_list===false or count($conn_list) === 0)
    //     {
    //         echo "finish\n";
    //         break;
    //     }
    //     $start_fd = end($conn_list);
    //     var_dump($conn_list);
    //     foreach($conn_list as $fd)
    //     {
    //         $serv-&gt;send($fd, "broadcast");
    //     }
    // }

    // var_dump($serv-&gt;connections);
    // foreach ($serv-&gt;connections as $k =&gt; $v) {
    //    $lk = [$k,$v];
    //    var_dump($lk);
    // }

});
$serv-&gt;on('close', function ($serv, $fd) {
    echo "Client: Close.\n";
});
$serv-&gt;start();

</code>
登录后复制

然后就可以开n个客户端,来测试下代码,比如我开3个telnet 127.0.0.1 1024,最后一个发消息给服务器"i am lucky man",第一个再对服务器发"broadcast to lucky man",那么第三个就会收到""some body broadcast to you luck man",实现对特定用户发送消息。

就是这么简单,
Swoole大法好,异步io+多进程 也是最成熟的结局方案(致敬Nginx)
哈哈哈

uid只是你识别的uid而已,socket链接到服务,都有一个唯一的id,你要对客户端发送消息只能通过这个唯一的id,你可以在这两者之间做个映射,那就可以了。

智能AI问答
PHP中文网智能助手能迅速回答你的编程问题,提供实时的代码和解决方案,帮助你解决各种难题。不仅如此,它还能提供编程资源和学习指导,帮助你快速提升编程技能。无论你是初学者还是专业人士,AI智能助手都能成为你的可靠助手,助力你在编程领域取得更大的成就。
相关标签:
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
关于CSS思维导图的课件在哪? 课件
凡人来自于2024-04-16 10:10:18
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号