Socket开发中如何在服务器GUI关闭时低资源消耗通知客户端
适配现有逻辑的低资源消耗实现方案
完全不需要客户端新增常驻监听连接,所有改动都基于现有“客户端点按钮才发单次请求、服务端收请求才回响应”的流程叠加,没有额外的网络和资源开销。
核心设计思路
把服务端的关闭状态存在服务端本地,复用客户端每次主动发请求的现有连接通道传递关闭通知。既不让客户端长期占着socket连接开后台监听线程,也避免服务端主动推消息的时候碰到一堆已经断了的连接,白忙活还报一堆错。
具体实现改动
服务端侧(贴合现有server.py逻辑,改动量极小)
- 全局维护两个几乎不占内存的轻量状态:
- 服务端运行标记
server_running,默认值设为True - 已交互客户端地址集合,每次收到客户端请求时,把对端的
(ip, 端口)元组存进去就行,不用留着长连接对象占内存
- 服务端运行标记
- 绑定服务端GUI的关闭按钮事件:用户点关闭按钮的时候,第一时间把
server_running改成False,这时候千万别主动去给所有记下来的客户端发关闭通知——本来就没保持长连接,你主动发的话,客户端那边连接早关了,发出去全是连接重置报错,纯纯浪费资源 - 复用原来的请求处理流程:等以后再收到客户端的请求、解析完JSON准备生成响应的时候,先看
server_running的状态:- 如果还是
True,和之前一样,调对应方法生成正常业务响应返回就行 - 如果已经是
False,啥业务逻辑都不用跑,直接返回带“服务端已关闭”标识的特殊响应 - 每次处理请求的时候,顺手把当前客户端的地址存到那个已交互集合里,只做个标记,不维持长连接
- 如果还是
- 等所有流程跑完要关服务端的时候,把那个客户端地址集合清空,正常释放socket资源就完事。
客户端侧(完全不新增常驻连接)
- 就保留原来“点按钮才开临时socket发请求”的逻辑,别加什么后台监听线程、别搞额外的长连接占资源
- 在原来的响应处理代码最前面加个判断:
- 收到服务端返回的东西,先检查有没有“服务端已关闭”的标识,有的话直接在GUI弹个提示,把所有需要连服务端的按钮置灰,别再走原来的业务渲染流程了
- 没有这个标识的话,和之前一样正常解析业务响应、渲染界面就行。
为什么这个方案比之前想的常驻连接靠谱
- 资源消耗极低:客户端全程只有用户主动操作的时候才开个几秒钟的短连接,没有后台挂着的监听线程、没有长期占着的TCP文件句柄,比单独开常驻连接的方案,内存、CPU、连接数占用低90%以上
- 完全不打乱现有代码结构:服务端就往原来的请求处理链路上加几行状态判断的代码,不用改原来的循环收包、捕
ConnectionResetError记日志、解析JSON的核心逻辑;客户端就往原来的响应处理里加一层判断,不用额外写网络模块 - 没有无效的推送开销:因为状态是客户端主动来拿的,根本不会出现服务端给早就离线的客户端发消息、报一堆错、堆一堆半关闭的TIME_WAIT连接的问题
- 逻辑上完全匹配需求:那些服务端关了之后再也不点交互按钮的客户端,本来就没和服务端交互的需求,根本没必要为了给这类用户推通知白搭资源。
内容的提问来源于stack exchange,提问作者null
相关产品推荐
相关产品推荐

