Hub

Landscape

hub-landscape.svg

  • Server 中 Hub 数量为 CPU * 2
  • register,unregister 应该用于连接接入或断开
  • broadcast 用于事件通知,可能包含广播消息、用户进入或退出 Channel、Team

Connection

hub-connection-index.svg

hubConnectionIndex 位于每一个 Hub 处理协程中,Hub 并不直接包含它。代码概要如下

  1. func (h *Hub) Start() {
  2. var doStart func()
  3. var doRecoverableStart func()
  4. var doRecover func()
  5. doStart = func() {
  6. // ...
  7. connections := newHubConnectionIndex()
  8. for {
  9. // ...
  10. }
  11. }
  12. doRecoverableStart = func() {
  13. defer doRecover()
  14. doStart()
  15. }
  16. doRecover = func() {
  17. if !h.ExplicitStop {
  18. // ...
  19. go doRecoverableStart()
  20. }
  21. }
  22. go doRecoverableStart()
  23. }

Add Connection

add-connection.svg

Remove Connection

remove-connection.svg

黄色线表示当 UserID 的最后一个 WebConn 在 Hub 中被移除后的处理。需要通过 Server 修改 Store,并向 Hub 通知有用户离线。如果存在集群,同时向集群广播,此处暂不涉及。

Broadcast

broadcast.svg

Procedure

web.Handler

web.Handler 实现了 http.Handler 接口,统一函数处理行为。web.Handler 的 ServeHTTP 方法中,实现了一般的中间件功能,实现过程如下图。
api-web-handler.svg

上图中,需要注意 web.Context 方法,主要作用是创建一个属于本次请求的 App 对象,App 是 Server 的功能代理,这样 Context 就包含了 Server,可以使用 Server 的功能。

如果 http.Request 中包含了 Token,说明发送请求的连接已经登陆系统,通过 App 获取 Session。无论是否登陆系统,后面都要执行 web.Handler 包含的处理方法。

Establish Connection

Login

用户登陆,通过用户名、密码或 oAuth 均可。登陆过程不做描述,登陆成功后,需要执行以下操作。
api-user-login.svg

Upgrade

api-ws-upgrader.svg

WebConn

Write Loop

api-web-conn-write-pump.svg

Read Loop

Pong Timeout

  1. func readPump() {
  2. // ...
  3. c.WebSocket.SetReadDeadline(time.Now().Add(PONG_WAIT))
  4. c.WebSocket.SetPongHandler(func(string) error {
  5. c.WebSocket.SetReadDeadline(time.Now().Add(PONG_WAIT))
  6. if c.IsAuthenticated() {
  7. c.App.Srv.Go(func() {
  8. c.App.SetStatusAwayIfNeeded(c.UserId, false)
  9. })
  10. }
  11. return nil
  12. })
  13. // ...
  14. }

Read Message

api-web-conn-read-message.svg

Dispatch Message

api-dispatch-message.svg