资讯专栏INFORMATION COLUMN

私聊(PHP 实现)

senntyou / 953人阅读

摘要:服务端设置阻塞模式在现有资源列表中找不到给定资源对应的索引在现有资源列表中找不到给定用户对应的客户端资源监听客户端连接监听客户端消息来自客户端的消息客户端接受客户端发来的消息下午时间到来自的消息客户端发送消息给客户端下午时间到来

服务端
$url = "tcp://0.0.0.0:9160";

$stream = stream_socket_server($url , $errno , $errstr);

// 设置阻塞模式
stream_set_blocking($stream , false);

$client_list = [];

$resource_list = [];

$resource_list[] = $stream;

$find= function($client) use(&$client_list){
   foreach ($client_list as $k => $v)
   {
       if ($v["resource"] === $client) {
           return $k;
       }
   }

   echo "在现有资源列表中找不到给定资源对应的索引" . PHP_EOL;

   return false;
};

$find_client = function($username) use(&$client_list) {
    foreach ($client_list as $v)
    {
        if ($v["username"] === $username) {
            return $v["resource"];
        }
    }

    echo "在现有资源列表中找不到给定用户对应的客户端资源" . PHP_EOL;

    return false;
};

while (true)
{
    $read = $resource_list;
    $write = $resource_list;
    $except = [];
    $wait_s = 0;
    $wait_us = 0;

    stream_select($read , $write , $except , $wait_s , $wati_us);

    foreach ($read as $v)
    {
        if ($v === $stream) {
            // 监听客户端连接
            $client = stream_socket_accept($v);

            if (is_resource($client)) {
                $resource_list[] = $client;

                $client_list[] = [
                    "username" => null ,
                    "resource" => $client
                ];
            }
        } else {
            $index = $find($v);
            $user  = $client_list[$index];

            // 监听客户端消息
            $msg = fread($v , 65535);

            if (!empty($msg)) {
                if (!is_null($user) && is_null($user["username"]) && preg_match("/username:(w+)/" , $msg , $matches) === 1) {
                    $client_list[$index]["username"] = $matches[1];
                } else {
                    $msg = unserialize($msg);

                    $client = $find_client($msg["to"]);

                    if ($client !== false) {
                        fwrite($client , serialize($msg));
                    } else {
                        echo "来自客户端的消息:from:{$msg["from"]};to:{$msg["to"]};msg:{$msg["msg"]}
";
                    }
                }
            }
        }
    }

    usleep(100 * 1000);
}
客户端 A(接受客户端 B 发来的消息)
 $username ,
    "to" => "yueshu" ,
    "msg" => "hello girl"
];

$is_flag = false;

while (true)
{
    $e_time = time();

    if ($e_time - $s_time > $duration) {
        echo "20s 时间到" . PHP_EOL;
        break;
    }

    if (!$is_flag) {
        fwrite($client , "username:" . $username);

        $is_flag = true;
    } else {
        // $sends = serialize($send);

        // fwrite($client , $sends);
    }

    $msg = fread($client , 65535);

    if (!empty($msg)) {
        $msg = unserialize($msg);

        echo "来自{$msg["from"]}的消息:{$msg["msg"]}
";
    }

    usleep(10 * 1000);
}
客户端 B(发送消息给客户端 A)
 $username ,
    "to" => "chenxuelong" ,
    "msg" => "hello boy"
];

$is_flag = false;

while (true)
{
    $e_time = time();

    if ($e_time - $s_time > $duration) {
        echo "20s 时间到" . PHP_EOL;
        break;
    }

    if (!$is_flag) {
        fwrite($client , "username:" . $username);

        $is_flag = true;
    } else {
        $send = serialize($msg);

        fwrite($client , $send);
    }

    /*
    $msg = fread($client , 65535);

    if (!empty($msg)) {
        $msg = unserialize($msg);

        echo "来自{$msg["from"]}的消息:{$msg["msg"]}
";
    }
    */

    sleep(1);
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/30684.html

相关文章

  • PHP即时通讯设计实现

    摘要:即时通讯中,最重要的是响应速度,我们需要展示消息列表那么这时会有未读消息,未读数量,最后一条消息内容,时间等等。目前设计是单表单库。这里只是对即时通讯设计上做了一些简要的阐述,如有疑问和建议,请在评论区回复。 详解即时通讯设计实现(PHP+GatewayWorker+Redis) 需要实现的功能 一对一聊天(私聊) 一对多聊天(群聊) 类似QQ,微信等聊天列表 实时消息 显示 工具...

    asoren 评论0 收藏0
  • PHP即时通讯设计实现

    摘要:即时通讯中,最重要的是响应速度,我们需要展示消息列表那么这时会有未读消息,未读数量,最后一条消息内容,时间等等。目前设计是单表单库。这里只是对即时通讯设计上做了一些简要的阐述,如有疑问和建议,请在评论区回复。 详解即时通讯设计实现(PHP+GatewayWorker+Redis) 需要实现的功能 一对一聊天(私聊) 一对多聊天(群聊) 类似QQ,微信等聊天列表 实时消息 显示 工具...

    luckyyulin 评论0 收藏0
  • PHP即时通讯设计实现

    摘要:即时通讯中,最重要的是响应速度,我们需要展示消息列表那么这时会有未读消息,未读数量,最后一条消息内容,时间等等。目前设计是单表单库。这里只是对即时通讯设计上做了一些简要的阐述,如有疑问和建议,请在评论区回复。 详解即时通讯设计实现(PHP+GatewayWorker+Redis) 需要实现的功能 一对一聊天(私聊) 一对多聊天(群聊) 类似QQ,微信等聊天列表 实时消息 显示 工具...

    leejan97 评论0 收藏0
  • 5分钟解决小程序的微信支付

    摘要:,之前在写过一篇微信支付教程手把手教你实现小程序的微信支付。说说必须要自己填写的东西开头的这几个信息都可以从小程序后台微信支付申请成功后发的邮件中拿到。 你好,是我琉忆,一个文艺的程序员。 很久没有更新什么技术文了,特在此补上一篇精华文章——微信支付。PS,之前在segmentfault写过一篇微信支付教程:手把手教你实现小程序的微信支付。【从发表开始,到现在被很多人收藏,加微信和QQ...

    forsigner 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<