SuperSocket icon indicating copy to clipboard operation
SuperSocket copied to clipboard

Linux下,WebSocket Server关闭一个超时连接失效,没触发OnSessionClosedAsync

Open shenyang1007 opened this issue 1 year ago • 5 comments

应用场景: 1.Linux操作系统 ,Almalinux,与redhat8相同 2.supersocket2.0.0-beta.28,websokcet server服务 3.连接超时需要断开连接,触发断开事件,做掉线业务处理。

问题: 1.通过看2.0源码发现是通过LastActiveTime来判断连接是否活跃的,但这里客户端发送消息与服务器发送消息都会重写该时间,所以当网络不好时(如关闭网络时),这时虽然客户端无法发送消息,但服务器不知道该连接断开,还是会不停给该连接发送消息(业务需要),这里LastActiveTime都是会不停刷新最新时间,没法断开。 2.自己写了一个超时业务判断 (心跳处理),只判断接收客户端发送消息的时间,也就是服务端接收到该连接发送的消息时间,如果大于超时限制时间时就手动断开连接,session.Connection.CloseAsync(CloseReason.TimeOut);,与ss2.0底层使用相同方法,这时虽然调用,但无法真正关闭,没触发OnSessionClosedAsync。其实这时服务端还是不停向该连接发送消息,不知是不是这里有判断 该连接pipe有消息,所以不会断开? 3.windows 平台不会出现该情况,在网络关闭后30s时间,服务端发送消息时会抛出异常,触发断开事件。 4.almalinux中,在网络关闭后15m的样子,也是发送消息会抛出异常,触发断开事件。

结果 : 1.希望close连接时,能立即触发断开事件,方便业务处理。根据自己超时判断业务, 2.能优化ss2.0底层库超时处理就更好

shenyang1007 avatar Dec 30 '24 11:12 shenyang1007

https://github.com/kerryjiang/SuperSocket/blob/5ca703e38b1616195672f0427e145d45fd2c8d83/src/SuperSocket.Connection/PipeConnection.cs#L165-L166

kerryjiang avatar Dec 30 '24 21:12 kerryjiang

上面代码是发送时更新最后活跃时间,这个我知道。但我现在问题是,我自己写了一个SessionManager,自己根据心跳来判断是否超时,然后手动调用session.Connection.CloseAsync(CloseReason.TimeOut),或是session.CloseAsync(),连接没有关闭掉,一直存在。

shenyang1007 avatar Dec 31 '24 01:12 shenyang1007

网络是不可靠的,你的SessionManger不应该管理连接的关闭,只需要调度Session就行了,连接关闭应该交给SuperSocket本身即可。

AsenLins avatar Jan 08 '25 08:01 AsenLins

SuperSocket 2.0.0-beta.31已经解决了这个问题。 https://www.nuget.org/packages/SuperSocket.Server/2.0.0-beta.31

kerryjiang avatar Apr 02 '25 20:04 kerryjiang

Please upgrade to SuperSocket 2.0.0.

kerryjiang avatar Apr 29 '25 23:04 kerryjiang