利用 webSocket 与 Swoole 打造一个小型聊天室(协程)

前言

    前面有写一个异步简单的聊天室,然后想着,就把协程的也弄了吧所以就有了这个文章,其实所有的功能都大差不差,就仅仅几个地方不一样而已,也都是简单的地方。
博文地址:利用 websocketswoole 打造一个小型聊天室 (异步)
本次也没增加功能,就是增加了一个心跳,从前端定时发送一个 ping ,服务端不作反应,仅此而已。

前端页面代码:

        打工人聊天室       .content {        height: 400px;        max-width: 400px;        overflow: auto;        border-radius: 5px;        border: 1px solid #f0f0f0;    }            

聊天区域

你好打工人:昵称
本次连接FD:

JS 代码:

    在服务器信息回执时,会有第一次连接回执,还是服务端发送消息回执的状态区别,通过 msgType 来分辨,如果是第一次连接的回执消息,则把 FD 做一个页面留存,并不显示在聊天消息区,如果收到的是消息回执,就直接显示到聊天消息区。

    还有就是,前后端相互通信发送的东西,都是字符串性质最优,我前端处理的方法是先组合成一个对象,然后转 JSON 串。

    //滚动条最底部    function scrolltest() {        var div = document.getElementById("content");        div.scrollTop = div.scrollHeight;    }    var wsServer = 'ws://127.0.0.1:9502/websocket';    var websocket = new WebSocket(wsServer);    var nickname = Math.random().toString(36).substr(2);    thisFd = '';    $('#nickname').html(nickname);    //点击发送    function send() {        var msg = $('#msg').val();        var data = {            'nickname': nickname,            'fd': thisFd,            'data': msg        }        //生成json 方便后台接收以及使用        var data = JSON.stringify(data);        websocket.send(data);        //然后清空        $('#msg').val('');    }    //链接成功    websocket.onopen = function (evt) {        var data = {            'msgType': 'open'        }        var data = JSON.stringify(data);        $("#content >p:last-child").after('

服务器已连接,开始聊天吧

'); websocket.send(data); }; //链接断开 websocket.onclose = function (evt) { $("#content >p:last-child").after('

服务器已断开,请重新连接

'); }; //收到服务器消息 websocket.onmessage = function (evt) { //握手成功后,会接受到服务端返回的fd ,msgType = 1 //字符串格式化成json var data = eval('(' + evt.data + ')'); // console.log(evt.data); switch (data.msgType) { case 1: thisFd = data.fd; $('#fd-samp').html(thisFd); $('#fd').val(thisFd); break; case 2: if (data.nickname == nickname) { data.nickname = '我'; } $("#content >p:last-child").after('

' + data.nickname + ' 在 ' + data.time + ' 说:
' + data.data + '

'); //接收到消息自动触底 scrolltest(); break; } }; //服务器异常 websocket.onerror = function (evt, e) { $("#content >p:last-child").after('

服务器异常

'); }; //心跳,本次新增 function heartbeat() { var data = { 'msgType': 'ping', } //生成json 方便后台接收以及使用 var data = JSON.stringify(data); websocket.send(data); } //30 秒一次 setInterval(heartbeat, 30000);

服务端代码
协程,都需要在 Corun(function () {}) 里。

<?php    //定义获取当前的id函数    function getObjectId(SwooleHttpResponse $response) {        if (PHP_VERSION_ID set([            'heartbeat_idle_time'      => 600, // 表示一个连接如果600秒内未向服务器发送任何数据,此连接将被强制关闭            'heartbeat_check_interval' => 60,  // 表示每60秒遍历一次        ]);        $server->handle('/websocket', function ($request, $ws) {            $ws->upgrade();            global $wsObjects;            $objectId = getObjectId($ws);            $wsObjects[$objectId] = $ws;            while (true) {                $frame = $ws->recv();                if ($frame === '') {                    unset($wsObjects[$objectId]);                    $ws->close();                    break;                } else if ($frame === false) {                    echo 'error : ' . swoole_last_error() . "n";                    break;                } else {                    if ($frame->data == 'close' || get_class($frame) === SwooleWebSocketCloseFrame::class) {                        unset($wsObjects[$objectId]);                        $ws->close();                        return;                    }                    //格式化接收到json                    $data = json_decode($frame->data);                    switch ($data->msgType){                        case 'open':                            //链接第一次                            $data = json_encode([                                'fd' => $objectId,                                'msgType' => 1  //代表第一次连接,前端处理fd                            ]);                            $ws->push($data);                            break;                        case 'ping':                            //接收到心跳 不作回复//                            echo  $data->msgType;                            break;                        default :                            // 原基础上不动,增加一些自定义                            $data->msgType = 2; //代表服务器端回复                            $data->time = date('Y-m-d H-i-s');                            $data = json_encode($data);                            foreach ($wsObjects as $obj) {                                $obj->push($data);                            }                    }                }            }        });        $server->start();    });

代码齐全之后,接下来就只需要在控制台执行以下 PHP 文件就行。
利用 webSocket 与 Swoole 打造一个小型聊天室(协程)

天工SkyMusic 天工SkyMusic

基于昆仑万维“天工3.0”打造的AI音乐生成工具,是目前国内唯一公开可用的AI音乐生成大模型

天工SkyMusic 247 查看详情 天工SkyMusic

然后前台直接访问你的网站地址,我的是本地 127.0.0.1
利用 webSocket 与 Swoole 打造一个小型聊天室(协程)

多开几个窗口模拟多个用户,然后发送消息测试即可:
利用 webSocket 与 Swoole 打造一个小型聊天室(协程)

你好,打工人。

代码很简单,难度不大,但是可以很简洁的反应出 webScoket 和 Swoole 的一种强大。

以上就是利用 webSocket 与 Swoole 打造一个小型聊天室(协程)的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/480035.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫

关于作者

上一篇 2025年11月8日 10:49:57
下一篇 2025年11月8日 10:59:29

相关推荐

发表回复

登录后才能评论
关注微信