Ruby eventmachine 如何释放 socket 连接

humbass · 2013年07月30日 · 最后由 luikore 回复于 2013年08月01日 · 3522 次阅读

用 eventmachine 搭建一个 socket 服务器,客户端连接上来后,断开,eventmachine 并没有自动销毁 socket 资源,而是会存在一定的时间,直到 tcp/ip 规定的超时时间

如何主动销毁失去连接的 socket 呢?

如果服务器知道写完哪些数据后可以断开连接,就主动用 close_connection_after_writing

客户端先断的话,EM 这边是会触发 unbind 的回调并关闭连接吧?

#1 楼 @luikore 主动断开用 close_connection_after_writing,客户端会失去连接 客户端先断开,EM 触发 unbind 后,用啥方法来关闭连接呢?EM 貌似没有相关的支持。

#2 楼 @humbass

客户端 close => 发送 FIN 数据包 => unbind 回调 => EM 自动关连接 全程不用手工做任何事情

但是有些特殊情况,客户端异常退出或者没调用 close, EM 这边就收不到 FIN 数据包,也不知道客户端是断开还是网络慢,就只能靠超时了。

不过你可以设置小一点的超时,用 connection.comm_inactivity_timeout =

谢谢!

我项目的应用客户端是长连接的,一般不断开,但由于是使用 GPRS 连接上来的,不可避免会出现断开的情况,GPRS 客户端检测到断开,会立即拨号重新连接,这样,eventmachine 在 receive_data 后,会建立新的线程,当然原来的线程在 tcp 超时前还会存在,但不影响新线程。

求教的地方是:当 eventmachie 在接受到同一个客户端连接上来后(可通过 receive_data 值来传递某些特征码),用什么方式可以直接断开之前的那个连接,让服务器的资源得到释放。

#4 楼 @humbass 假设用 user_id 分辨是否同一用户,我能想到的一个笨办法是,保存一个全局的映射 MAP = {user_id => conn}, 然后:

  • receive_data 时检查 MAP[user_id] == self 如果不同就关掉旧连接
  • 为避免 MAP 泄漏,在 unbind 时也清理一下对应项
sqsy 整理学习 EventMachine 的一些文章和帖子 提及了此话题。 09月08日 17:05
需要 登录 后方可回复, 如果你还没有账号请 注册新账号