php websocket 心跳包,番外、Workerman中维护心跳包(Websocket为例)

# 1\. 什么是心跳

其实简单的说就是:客户端隔一段时间就给服务端发送消息,用来告诉服务端这个连接没有断,是正常的,从而维护长连接的持久性。

如果不加心跳包,有的服务器节点(防火墙)会自动把一定时间之内没有数据交互的连接给断掉;而且这中间指不定会有什么乱七八糟的比如机器断电、网线拔出这些幺蛾子出现导致客户端断线。

但是类似断网这种**极端情况**导致客户端断开连接,服务端是不知道的。因为客户端在正常情况下主动断开会向服务端发送一个tcp的fin包。

> 什么是FIN包?

> FIN包表示发送端已经达到数据末尾,也就是说双方的数据传送完成,没有数据可以传送了。

> 发送FIN标志 位的TCP数据包后,连接将被断开。

> 这个标志的数据包也经常被用于进行端口扫描。

然而极端情况下,客户端没有机会发这个包,就会导致服务端并不知道客户端断掉了。

# 2\. 长连接必须加心跳

长连接,只要是长连接,长时间不通讯肯定会被防火墙干掉然后断开,服务在非可控情况下断开是非常不好的情况;所以长连接无论如何都要加上心跳包。

# 3\. 心跳实例

接下来以workerman建立websocket连接为实例。

## 3.1 前端JavaScript代码

在onopen连接建立的时候,定义一个定时器,每10秒钟发送一个包,包的内容随意。

~~~

var ws = new WebSocket("ws://www.goozp.com");

//连接websocket

ws.onopen = function () {

setInterval(function () {

ws.send('Hello!');

}, 10000)

};

~~~

一般发送心跳包的间隔在60秒以内。

## 3.2 Workerman中处理断线

此处参考:[官方文档:心跳](http://doc.workerman.net/315282 "官方文档:心跳")

可以先定义一些常量在之后用到,方便配置:

~~~

define('HEARTBEAT_TIME', 30); // 定义一个心跳间隔30秒

define('CHECK_HEARTBEAT_TIME', 1); // 检查连接的间隔时间

~~~

当接收到信息时,我们就记录下接收到信息的时间:

~~~

$worker->onMessage = function($connection, $msg) {

// 给connection临时设置一个lastMessageTime属性,用来记录上次收到消息的时间

$connection->lastMessageTime = time();

// TODO 其它业务逻辑...

};

~~~

在进程启动后设置一个定时器,每隔一段时间遍历一遍当前worker的所有连接

~~~

// 进程启动后设置一个每秒运行一次的定时器

$worker->onWorkerStart = function($worker) {

Timer::add(CHECK_HEARTBEAT_TIME, function()use($worker){

$time_now = time();

foreach($worker->connections as $connection) {

// 有可能该connection还没收到过消息,则lastMessageTime设置为当前时间

if (empty($connection->lastMessageTime)) {

$connection->lastMessageTime = $time_now;

continue;

}

// 上次通讯时间间隔大于心跳间隔,则认为客户端已经下线,关闭连接

if ($time_now - $connection->lastMessageTime > HEARTBEAT_TIME) {

$connection->close();

}

}

});

};

~~~

这样,结合前端的心跳包,我们就可以做到维持连接的长久,以及踢出设置时间段内未使用的废弃连接。

>好文转载,此章节转载地址:[咖啡与代码](https://www.goozp.com/category/workerman) -(原作者如有要求,会立马下架此章节)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值