深入学习swoole之长连接(心跳检测)

同步客户端(swoole tcp(短连接))

同步client是同步阻塞的,一整套connect->send()->rev()->close();是同步进行的;
当一个同步调用发出去后,调用者要一直等待调用结果的通知后,才能进行后续的操作;
生活中的例子:
  同步:小明点单交钱,然后等着拿奶茶;

异步客户端(swoole tcp(长连接))

异步client是非租塞的,不用阻塞当前线程来等待处理完成,而是允许后续操作,直至其它线程将处理完成,并回调通知此线程;
生活中的例子:
  异步:小明点单交钱,店员给小明一个小票,等奶茶做好了,小明再来取;

心跳检测(长连接)

1. 什么是心跳:

顾名思义,心跳是判断一个事物是生还是死的标准,在swoole里,心跳是指用来判断一个连接是正常还是断开的状态;


2. 为什么要心跳:

心跳的目的其实是通过判断客户端是否存活,从而回收fd,系统为什么要回收fd,因为fd资源是有限的,所以必须重复利用

心跳的主要两个作用:

  1. 客户端定时给服务端发送点数据,防止连接由于长时间没有通讯而被节点防火墙关闭导致连接断开的情况;

  2. 服务端通过心跳来检测客户端是否在线,如果客户端在规定的时间没有发来任何数据,就认为客户端下线,这样可以检测到客户端由于极端情况(断电,断网等),从而触发客户端下线事件;


3. 心跳在swoole里的实现:

swoole会在主进程独立启动一个心跳线程,通过定时轮询所有的连接,来判断连接的生死,所以swoole的心跳不会堵塞任何业务逻辑;

服务端:

$serv->set(array(
   'heartbeat_check_interval' => 1,//服务器定时检测在线列表的时间
   'heartbeat_idle_time' => 10, //连接最大的空闲时间
     (如果最后一个心跳包的时间与当前时间之差超过这个值,则认为该连接失效)
));


客户端:
//使用定时器,定时向服务端发送数据包
swoole_timer_tick(1000, function() use ($cli){
   $cli->send("1");
});


为什么需要心跳包?客户端如何维持心跳?

   在客户端到服务器的一条巨大的链路中会经过无数的路由器,其中每一个路由器都有可能检测到多少秒时间内无数据包则自动关闭连接的这种节能机制,为了让这个可能会出现的节能机制失效,客户端可以设置一个定时器,每隔固定的时间都发一个随机的字符的一个字节的是数据包,通常我们把这种数据包叫做心跳包;

配置建议: heartabeat_idle_time 为 heartabeat_cheak_interval 的两倍多一点, 这个两倍是为了进行容错,允许丢一个包,多一点是考虑到网络的延时;

MyAnswer博客


MyAnswer博客
请先登录后发表评论
  • 最新评论
  • 总共0条评论