Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

128 linhas
2.9KB

  1. package main
  2. import (
  3. "github.com/brianvoe/gofakeit/v6"
  4. "github.com/gorilla/websocket"
  5. log "github.com/sirupsen/logrus"
  6. "sync"
  7. )
  8. type wsQ struct {
  9. wsMutex sync.Mutex
  10. Clients map[*websocket.Conn]string
  11. ClientsBySocketId map[string]*websocket.Conn
  12. ClientToSessionId map[*websocket.Conn]string
  13. }
  14. var wsq = wsQ{
  15. Clients: make(map[*websocket.Conn]string),
  16. ClientsBySocketId: make(map[string]*websocket.Conn),
  17. ClientToSessionId: make(map[*websocket.Conn]string),
  18. }
  19. func (m *wsQ) addConnection(c *websocket.Conn) (socketId string) {
  20. m.wsMutex.Lock()
  21. socketId = gofakeit.UUID()
  22. m.Clients[c] = socketId
  23. m.ClientsBySocketId[socketId] = c
  24. m.wsMutex.Unlock()
  25. m.debugNumOfClients()
  26. m.informClient(c, socketId)
  27. return
  28. }
  29. func (m *wsQ) informClient(conn *websocket.Conn, socketId string) {
  30. msg := make(map[string]string)
  31. msg["T"] = "assign-socketId"
  32. msg["socketId"] = socketId
  33. _ = wsSendByConn(conn, msg)
  34. }
  35. func (m *wsQ) debugNumOfClients() {
  36. m.wsMutex.Lock()
  37. numOfClients := len(m.Clients)
  38. numOfClientsById := len(m.ClientsBySocketId)
  39. m.wsMutex.Unlock()
  40. log.Info("number of concurrent websocket is ", numOfClients, numOfClientsById)
  41. }
  42. func (m *wsQ) MapSessionToConnection(sid string, c *websocket.Conn) {
  43. m.wsMutex.Lock()
  44. m.ClientToSessionId[c] = sid
  45. m.wsMutex.Unlock()
  46. }
  47. func (m *wsQ) RemoveSession(sessionId string, c *websocket.Conn) {
  48. m.wsMutex.Lock()
  49. for conn, v := range m.ClientToSessionId {
  50. if v == sessionId {
  51. delete(m.ClientToSessionId, conn) // remove connection to session map
  52. if socketId, exist := m.Clients[conn]; exist {
  53. delete(m.Clients, conn)
  54. delete(m.ClientsBySocketId, socketId)
  55. }
  56. }
  57. }
  58. m.wsMutex.Unlock()
  59. }
  60. func (m *wsQ) has(conn *websocket.Conn) (yes bool) {
  61. m.wsMutex.Lock()
  62. _, ok := m.Clients[conn]
  63. m.wsMutex.Unlock()
  64. return ok
  65. }
  66. func (m *wsQ) getConnBySessionId(sid string) (conn *websocket.Conn) {
  67. conn = nil
  68. m.wsMutex.Lock()
  69. for k, v := range m.ClientsBySocketId {
  70. if k == sid {
  71. conn = v
  72. break
  73. }
  74. }
  75. m.wsMutex.Unlock()
  76. return
  77. }
  78. func (m *wsQ) del(conn *websocket.Conn) {
  79. m.wsMutex.Lock()
  80. if sid, exist := m.Clients[conn]; exist {
  81. delete(m.Clients, conn)
  82. delete(m.ClientsBySocketId, sid)
  83. }
  84. m.wsMutex.Unlock()
  85. m.debugNumOfClients()
  86. }
  87. func (m *wsQ) delBySessionId(sid string) {
  88. m.wsMutex.Lock()
  89. if conn, exist := m.ClientsBySocketId[sid]; exist {
  90. delete(m.ClientsBySocketId, sid)
  91. delete(m.Clients, conn)
  92. }
  93. m.wsMutex.Unlock()
  94. m.debugNumOfClients()
  95. }
  96. func (m *wsQ) wsDoBroadcast(msg string, except string) {
  97. toBeRemoved := make([]*websocket.Conn, 0, 20)
  98. m.wsMutex.Lock()
  99. for k, _ := range m.Clients {
  100. if m.ClientsBySocketId[except] == k {
  101. continue
  102. }
  103. err := k.WriteMessage(websocket.TextMessage, []byte(msg))
  104. if err != nil {
  105. toBeRemoved = append(toBeRemoved, k)
  106. }
  107. }
  108. // remove all those have errors for communication
  109. for _, v := range toBeRemoved {
  110. delete(m.Clients, v)
  111. }
  112. m.wsMutex.Unlock()
  113. }