swoole 的练习 demo(5)- 加入心跳功能

swoole 的练习 demo(5)- 加入心跳功能

一直不能下决心好好学习,仔细研究一下,决定用尽量降低难度曲线的方法,从易到难,一步一步的学习,所以整了个demo项目。

git仓库和使用步骤

确保能看到swoole,在 php -m 命令中
php -m 
git clone https://github.com/lang123789/swoole_demo.git
然后设置了标签,本文对应 v5.0
cd swoole_demo
git checkout v5.0

有提示错误之类,但代码已经切换到 v5.0 了。

## 安装类库,生成 autoload.php 文件
composer install
## 启动 websocket 服务
php src/WebSocket/run.php

需求

9、加入心跳功能,确保用户不输入的情况下,只要页面打开,则应该长连接保持。

测试网址

127.0.0.1/index.php?id=1

主要代码

客户端主要代码

客户端代码主要在 index.php 中

window.onload = function() {
    activate_chat_js();

    var wsServer = 'ws://{$JS_IP}:9501';
    var websocket = new WebSocket(wsServer);
    window.websocket = websocket;
    websocket.onopen = function(evt) {
        console.log("Connected to WebSocket server.");
        heartCheck.reset().start(); //心跳检测重置
        websocket.send("my_id|{$user_id}");
    };

    websocket.onclose = function(evt) {
        console.log("Disconnected");
    };

    websocket.onmessage = function(evt) {
        console.log('从服务器接受的数据 ' + evt.data);
        // 心跳最前面检测
        if (evt.data == 'pong') {
            heartCheck.reset().start(); //心跳检测重置
            return;
        }


        var user = JSON.parse(evt.data);
        if (user.type == 'my_id') {
            system_chatWindow(user.message);
        }
        // v4.0修改。其他人接受某人的消息广播。
        if (user.type == 'my_message') {
            update_chatWindow2(user.message, user.from_user_name);
        }

    };

    websocket.onerror = function(evt, e) {
        console.log('Error occured: ' + evt.data);
    };

    var heartCheck = {
        timeout: 5000,
        //单位毫秒,5秒发一次心跳,改成61000,就是61秒就会被服务器自动断掉,
        // 说明,只需这个值大于 服务器的heartbeat_idle_time 与 heartbeat_check_interval 的和,就一定会自动停掉。
        timeoutObj: null,
        serverTimeoutObj: null,
        reset: function() {
            clearTimeout(this.timeoutObj);
            clearTimeout(this.serverTimeoutObj);
            return this;
        },
        start: function() {
            var self = this;
            this.timeoutObj = setTimeout(function() {
                //这里发送一个心跳,后端收到后,返回一个心跳消息,
                //onmessage拿到返回的心跳就说明连接正常
                websocket.send("ping");
                console.log("ping")

            }, this.timeout)
        }
    };

}

服务端主要代码

        $this->server = new \swoole_websocket_server(
            $this->config['socket']['host'],
            $this->config['socket']['port']
        );

        //v5.0 设置心跳检测
        $this->server->set(array(
            'heartbeat_idle_time'      => 30, // 表示一个连接如果30秒内未向服务器发送任何数据,此连接将被强制关闭
            'heartbeat_check_interval' => 25,  // 表示每25秒遍历一次
        ));
public function message(\swoole_websocket_server $server, \swoole_websocket_frame $frame)  {

        $data = $frame->data;
        echo "有消息:".$data."\n";
        //这里用户发来的信息已经分类型了。my_id开头,说明是系统自动从客户端发送的信息,用于识别身份。

        if (preg_match('#^ping#', $data)) {
            echo "心跳来了 " .date("Y-m-d H:i:s")."\n";
            $server->push($frame->fd,'pong');// 返回一个消息,过会他会再次传来。

        } elseif (preg_match('#^my_id#', $data)) {
            $user_id = explode("|", $data)[1];
            $arr = $this->user_all;
            $user_name = isset($arr[$user_id]) ? $arr[$user_id] : '';
        //。。。。。
        }
    }

WebSocketServer.php 是核心文件。

代码说明

1、客户端每隔多少秒发送一次消息给服务器,防止服务器断长连接。
2、只需这个值大于 服务器的heartbeat_idle_time 与 heartbeat_check_interval 的和,就一定会自动停掉。
3、保险起见,客户端的定时的值,需要小于heartbeat_idle_time 值。
4、heartbeat_idle_time 表示服务器发现某客户端多长时间不联系服务器,就主动断
5、heartbeat_check_interval 表示服务器每隔多长时间来检测这个心跳。显然应小于heartbeat_idle_time
6、客户端在 onopen 和 onmessage 这两个方法里进行定时器设置,具体象打乒乓球,客户端发出ping,服务器立刻返回,客户端间隔一定时间,再次ping,服务器总是立刻返回。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
51
粉丝
7
喜欢
60
收藏
94
排名:588
访问:1.3 万
私信
所有博文
社区赞助商