嵌入式工程师互助:34分钟12问14答解决“服务器端定时检测在线的客户端—心跳处理”
背景:如果您有棘手的技术问题,您会选择什么方式解决?百度一下搜索网络答案?还是找一位高手求问!高手可遇不可求,实际问题场景中,也是仁者见仁或猴子快上树或鸟儿空中飞,互联网飞速发展,IT168企业级一直陪伴着大家,从论坛、全国技术沙龙到技术峰会(DTCC\SACC\高峰精英论坛),我们一直在努力平衡“广大技术从业者技术提升”与“IT厂商新产品及服务的普及。我们一直在路上,或行走或奔跑,我们路行之风,是否能凉爽到路过的你?关于技术问与答,建议加入IT欢乐群及各分类技术群!261358889群号关于技术快速集训营:建议参与我们的数据库大会、架构师大会、IT精英论坛!
最新消息:架构师大会将于2015年10月22日盛大开幕!购票入口:http://sacc.it168.com/
赠票活动:技术自白书征文活动 http://bbs.chinaunix.net/thread-4181131-1-1.html
以下内容产生于6月25日22:47-23:11 IT欢乐群之分类技术QQ群!在此感谢,回答与提问者的精进,技术生活虽平淡,却因有你们的无私与勤恳而更精彩!
问:若客服端在一定时间内没向服务器端发送消息,就将此客服端从服务器例表删除,就是心跳包要怎么处理?
答:比如你可以客户端每隔20秒向服务器端发送一个http格式的心跳包
问:我是从键盘获取。用fgets()
答:思路明确没?现在卡在哪?
问:我该如何判断fgets(buff, N, stdin);在一点时间内是没有输入的?只要判断它在一点时间内没有输入就让服务器对其做下线处理
答:(1)能不能加信号,键盘输入应该会出发信号。
(2)可以写个倒计时啥的时间结束还没收到就让其下线。
问:我想到过用select,但是服务器端要接收多个客户端的消息并处理啊,我服务器端使用链表实现客户端用户存储的,所以I/O多用复用又不好整了。
答:你应该换个思路。
问:您说该怎么换思路,求指教
答:最好定期发给服务端发一个消息,就是心跳,服务端收不到就删除对应的用户节点。
问:嗯 ,那这个心跳包和键盘的输入怎么平衡呢?
答:(1)不影响的,在心跳之内还没发就下线啊
(2)心跳要有固定格式,发过去服务器端解析出,只要格式正确就保持在线。
问:定义一个结构体?
答:(1)对自己约定一个格式就好=哪怕是一个字符
(2)不是就是一个字符串就行,加关键字。这样做还有一个好处,比如客户端完成任务后可以向服务器端发请求下线,服务器端只要做消息处理就行。
问:那请问在服务器端该怎么在链表里去处理呢?就像我有写客户端发送quit,客户端就下线 ,服务器端就删除该用户
答:你一个连标节点就是一个用户对吧。
问:是
答:那个节点发的消息就处理哪个节点。
问:每个节点 一个用户?
答:嗯,对,就那样。理解了吗?
问:再请教一个较基础的问题,请问在客户端那个定时该怎么做,用sleep睡眠?
答:就是一个while循环,每隔多少秒不停发心跳。最好用一个计算时间查的小算法。还有为了保证数据的安全或准确行最好发送消息时用协议包装 这个你先慢慢来。
占楼:lol:lol:lol:lol:lol :emn23:来顶 标题的“客服端”应该改“客户端” :D 好滴 不错不错,可以定期更新top questions, 本帖最后由 yulihua49 于 2015-07-11 19:18 编辑
小尾巴鱼 发表于 2015-07-02 11:12 static/image/common/back.gif
背景:如果您有棘手的技术问题,您会选择什么方式解决?百度一下搜索网络答案?还是找一位高手求问!高手可 ...答:就是一个while循环,每隔多少秒不停发心跳。最好用一个计算时间查的小算法。还有为了保证数据的安全或准确行最好发送消息时用协议包装 这个你先慢慢来。
没这么简单。
你必须保证心跳不干扰正常通信。做业务时心跳必须停。
心跳等待应答期间业务要等待心跳完成。
我更倾向不用心跳。不用时关闭连接,使用时打开。这个工作可以交给连接池处理。
应用对连接池的调用就是取用和归还。取用时发现连接失效可以重连。连接池发现连接长时间不用可以自动关闭。
如果应用使用频繁,那它本身就是心跳。如果使用不频繁,那就没必要老开着连接。 本帖最后由 yulihua49 于 2015-07-11 19:25 编辑
小尾巴鱼 发表于 2015-07-02 11:12 static/image/common/back.gif
背景:如果您有棘手的技术问题,您会选择什么方式解决?百度一下搜索网络答案?还是找一位高手求问!高手可 ...问:若客服端在一定时间内没向服务器端发送消息,就将此客服端从服务器例表删除,就是心跳包要怎么处理?
答:比如你可以客户端每隔20秒向服务器端发送一个http格式的心跳包
答非所问。人家问客户的没发信息怎么处理。
正确答案是利用超时机制发现客户端超时。
一般可以用TCP超时,setsocketopt。 有的系统不支持。epoll和select也不支持,就需要自己设置超时监控子系统,通常单独用个线程。
它监控每一个连接的状态,发现哪个超时就发通知把它从等待队列清除,并进行善后工作。 yulihua49 发表于 2015-07-11 16:48 static/image/common/back.gif
没这么简单。
。。。。。。
取用时发现连接失效可以重连
。。。。。。
..
连接失效是个什么状态?
如何重连对方,对方又没有listen? 本帖最后由 yulihua49 于 2015-07-31 19:40 编辑
要看连接池的状态。如果初始状态(一切连接均无效),就产生新连接。这自然知道是否成功。长时间不用的连接被强制恢复成初始态。结果同上。使用中的连接,发现故障(发送或接收错误),需要自行夭折你的后续操作。当前的故障连接要归还并关闭。这个连接自然恢复到初始态。一般的连接故障不可能很快恢复,所以没必要自动重连。业务的rollback,redo,abort等操作你自己设计
连接池是个客户端的装置。服务器不是这样的,它只需要超时关闭客户端连接即可,我们一般设置服务器超时6分钟,客户端(连接池)超时5分钟。这样总是保证客户端抢先关闭。应用不会出任何问题。如果客户端一直繁忙,服务器也不会探测到超时。双方的超时都是在发生真正的网络故障。
把我的回帖完整看一遍就可以理解了。
页:
[1]