我是HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,发送加微信,交个朋友),转发本文前需获得作者HullQin授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋等游戏,不收费没广告。还开发了《Dice Crush》参加Game Jam 2022。喜欢可以关注我 HullQin 噢~我有空了会分享做游戏的相关技术。
背景
在专栏《Go WebSocket》里,有一些前置文章:
第一篇文章:《为什么我选用Go重构Python版本的WebSocket服务?》,介绍了我的目标。
第二篇文章:《你的第一个Go WebSocket服务: echo server》,介绍了一下怎么写一个WebSocket server。
第三篇文章:《单房间的聊天室》,介绍了如何实现一个单房间的聊天室。
第四篇文章:《多房间的聊天室(一)思考篇》,介绍了实现一个多房间的聊天室的思路。
第五篇文章:《多房间的聊天室(二)代码实现》,介绍了实现一个多房间的聊天室的代码。
如果你没阅读上面的文章,一定要先看一下,因为这篇文章更复杂,如果你不弄懂上面几篇,这篇可能跟不上节奏噢。
上篇文章我们提到:
现在房间数只会源源不断的增多,house这个map会越来越大,终将造成内存不足,这不是一个好事情。
所以我们后续需要加一个优化:当最后一个客户端断开连接时,回收(删除)这个房间。
今天,我们实现它。
思路
有一个重要的问题需要想清楚:
是在哪个地方执行这个【回收】操作?是哪个goroutine?什么时机?若有多个地方,有没有竞争关系?
回顾一下之前绘制的图:
可以发现:每个客户端连接会常驻2个goroutine:Read和Write。其中Read重要的职责就是unregister
,这点我之前在《单房间的聊天室》强调过。
unregister
就是把客户端连接从hub中删除掉。这个时候,我们就可以检查一下hub内是否还有其它客户端,若无,则删除。
注意,unregister
只是个channel,真正的处理逻辑是写在goroutine中的,是哪个gotoutine负责接收unregister
并执行逻辑呢?就是Hub
。所以我们需要修改Hub
代码。
直接看源码
多房间聊天室案例代码的地址:github.com/HullQin/go-websocket-examples
在chat-multi-rooms
文件夹中,文章可配套commit记录阅读: