乐趣区

关于后端:Go-WebSocket-多房间的聊天室一思考篇

我是 HullQin,公众号 线下团聚游戏 的作者(欢送关注公众号,发送加微信,交个敌人),转发本文前需取得作者 HullQin 受权。我独立开发了《联机桌游合集》,是个网页,能够很不便的跟敌人联机玩斗地主、五子棋等游戏,不免费没广告。还开发了《Dice Crush》加入 Game Jam 2022。喜爱能够关注我 HullQin 噢~我有空了会分享做游戏的相干技术。

背景

第一篇文章:《为什么我选用 Go 重构 Python 版本的 WebSocket 服务?》,介绍了我的指标。

第二篇文章:《你的第一个 Go WebSocket 服务: echo server》,介绍了一下怎么写一个 WebSocket server。

第三篇文章:《单房间的聊天室》,介绍了如何实现一个单房间的聊天室。

明天咱们实现一个多房间的聊天室。如果你没浏览下面的文章,肯定要先看一下,因为这篇文章更简单,如果你不弄懂下面几篇,这篇可能跟不上节奏噢。

以第三篇文章的代码为终点

明天,咱们批改上次「聊天室」的代码即可。

因为 gorilla/websocket 官网并未提供多房间聊天室的 demo,只提供了单房间聊天室的 demo(就是上篇文章所讲的),这次咱们要本人入手开发啦!

思考

还记得上次绘制的架构图吗?

这次,咱们要入手改代码了!先不要间接写代码,咱们先画图!理清思路,代码就信手拈来了!

以前,咱们全局只有 1 个 Hub goroutine,而播送(broadcast)正是依赖了这个 goroutine。客户端把心愿播送的音讯传到 broadcast 这个 channel 里,由Hub goroutine 读取 broadcast channel,遍历它的 clients,把音讯写入 send channel,再由各个客户端的 Write goroutine 读取 send channel,发送音讯。

当初既然要实现多房间,Hub goroutine应该有多个。具体表现应该是这样:

何时创立房间

上一篇文章,咱们只有一个房间,所以在服务启动时,在 main 函数里曾经启动了Hub goroutine,然而这次不行了。咱们可能有多个房间,所以有两种计划。

计划一:设置固定的几个房间

如果房间数目是固定的,例如你设置了一共只有 10 个房间,那么你齐全能够参考上篇文章,只不过这次要调用 10 次 go hub.run() 了。因为每次调用就启动一个 goroutine,10 个房间就是 10 次。

计划二:动态创建房间

如果房间容许动态创建,那么你就须要在客户端连贯时,给你传入一个「房间号」参数,你须要判断以后「房间号」是否存在,如果不存在,须要被动创立(调用go hub.run()),如果存在,就用存在的房间。

论断

如果是计划一,没有挑战性,参考上篇文章,你也能够轻松实现。明天咱们依照计划二来做。

如何决定客户端连哪个房间

既然咱们有多个房间,客户端是肯定须要通知服务端:我要进哪个房间的。有 3 个罕用计划:

计划一:URL 里指定

咱们能够在连贯 WebSocket 时,在 URL 里指定(通过门路或参数)。上篇文章,咱们对 WebSocket 服务定义的路有规定是/ws。能够再裁减一下,变为/ws/【房间号】。读取【房间号】即可。

计划二:cookie 里指定

在连贯 WebSocket 时,会把以后域名的 cookie 也带过来,服务端能够读取的到。因而,也能够把房间号信息存到 cookie 里。

注:「cookie 指定」这种形式很罕用,尤其是网页里的【用户音讯】,如果有人给你点赞、关注,这个音讯须要实时推送给用户。而且如果你多开了几个 Tab,这些 Tab 都应该收到。这种状况下,你的每个浏览器 Tab 就是一个「Client」,你这个账号就是一个「Room」。(这时候 Room 就是一个抽象概念了,不能把它当作是一个实在的房间,只能当作一个连贯池子,播送音讯时,这个池子里的所有 Client 会收到雷同的音讯)

计划三:连贯实现时,客户端被动发一个音讯,表明房间

这个跟计划一、二有实质不同。计划一、二在 WebSocket 连贯时,就确定了房间号,效率更高。然而计划三是在连贯实现时,客户端被动发一个音讯,告知服务端房间号。

尽管效率不如计划一、二,然而更加灵便,扩展性好。因为那个音讯里能够附带更多的信息。

这也是很多利用采取的计划,大胆用吧!因为效率影响能够忽略不计,然而可扩展性影响太大了,会影响你将来几年的保护老本!

为什么不放在 header 信息?

因为 WebSocket 协定其实不倡议把信息放在自定义 header 里。你看建设 WebSocket 连贯的 JS API 的语法:

不像 Http 申请 APIfetchWebSocket不容许用户传入 header 参数。如果你想传递额定信息,官网倡议就是三种:URL、cookie、连贯建设后发个音讯。本文均已列举。

好了。以上就是本篇内容了,下一篇,咱们进入【实际篇】,写代码,实现一个多房间的聊天室。

写在最初

我是 HullQin,公众号 线下团聚游戏 的作者(欢送关注公众号,发送加微信,交个敌人),转发本文前需取得作者 HullQin 受权。我独立开发了《联机桌游合集》,是个网页,能够很不便的跟敌人联机玩斗地主、五子棋等游戏,不免费没广告。还开发了《Dice Crush》加入 Game Jam 2022。喜爱能够关注我 HullQin 噢~我有空了会分享做游戏的相干技术。

退出移动版