websocket 增加多分组 fork https://github.com/olahol/melody
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

155 lines
4.1 KiB

10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package melody
  2. import (
  3. "github.com/gorilla/websocket"
  4. "net/http"
  5. "sync"
  6. )
  7. type handleMessageFunc func(*Session, []byte)
  8. type handleErrorFunc func(*Session, error)
  9. type handleSessionFunc func(*Session)
  10. type filterFunc func(*Session) bool
  11. // Melody implements a websocket manager.
  12. type Melody struct {
  13. Config *Config
  14. Upgrader *websocket.Upgrader
  15. messageHandler handleMessageFunc
  16. messageHandlerBinary handleMessageFunc
  17. errorHandler handleErrorFunc
  18. connectHandler handleSessionFunc
  19. disconnectHandler handleSessionFunc
  20. pongHandler handleSessionFunc
  21. hub *hub
  22. }
  23. // New creates a new melody instance with default Upgrader and Config.
  24. func New() *Melody {
  25. upgrader := &websocket.Upgrader{
  26. ReadBufferSize: 1024,
  27. WriteBufferSize: 1024,
  28. }
  29. hub := newHub()
  30. go hub.run()
  31. return &Melody{
  32. Config: newConfig(),
  33. Upgrader: upgrader,
  34. messageHandler: func(*Session, []byte) {},
  35. messageHandlerBinary: func(*Session, []byte) {},
  36. errorHandler: func(*Session, error) {},
  37. connectHandler: func(*Session) {},
  38. disconnectHandler: func(*Session) {},
  39. pongHandler: func(*Session) {},
  40. hub: hub,
  41. }
  42. }
  43. // HandleConnect fires fn when a session connects.
  44. func (m *Melody) HandleConnect(fn func(*Session)) {
  45. m.connectHandler = fn
  46. }
  47. // HandleDisconnect fires fn when a session disconnects.
  48. func (m *Melody) HandleDisconnect(fn func(*Session)) {
  49. m.disconnectHandler = fn
  50. }
  51. // HandlePong fires fn when a pong is received from a session.
  52. func (m *Melody) HandlePong(fn func(*Session)) {
  53. m.pongHandler = fn
  54. }
  55. // HandleMessage fires fn when a text message comes in.
  56. func (m *Melody) HandleMessage(fn func(*Session, []byte)) {
  57. m.messageHandler = fn
  58. }
  59. // HandleMessageBinary fires fn when a binary message comes in.
  60. func (m *Melody) HandleMessageBinary(fn func(*Session, []byte)) {
  61. m.messageHandlerBinary = fn
  62. }
  63. // HandleError fires fn when a session has an error.
  64. func (m *Melody) HandleError(fn func(*Session, error)) {
  65. m.errorHandler = fn
  66. }
  67. // HandleRequest upgrades http requests to websocket connections and dispatches them to be handled by the melody instance.
  68. func (m *Melody) HandleRequest(w http.ResponseWriter, r *http.Request) {
  69. conn, err := m.Upgrader.Upgrade(w, r, nil)
  70. if err != nil {
  71. m.errorHandler(nil, err)
  72. return
  73. }
  74. session := &Session{
  75. Request: r,
  76. Keys: nil,
  77. conn: conn,
  78. output: make(chan *envelope, m.Config.MessageBufferSize),
  79. melody: m,
  80. lock: &sync.Mutex{},
  81. }
  82. m.hub.register <- session
  83. m.connectHandler(session)
  84. go session.writePump()
  85. session.readPump()
  86. if m.hub.open {
  87. m.hub.unregister <- session
  88. }
  89. go m.disconnectHandler(session)
  90. }
  91. // Broadcast broadcasts a text message to all sessions.
  92. func (m *Melody) Broadcast(msg []byte) {
  93. message := &envelope{t: websocket.TextMessage, msg: msg}
  94. m.hub.broadcast <- message
  95. }
  96. // BroadcastFilter broadcasts a text message to all sessions that fn returns true for.
  97. func (m *Melody) BroadcastFilter(msg []byte, fn func(*Session) bool) {
  98. message := &envelope{t: websocket.TextMessage, msg: msg, filter: fn}
  99. m.hub.broadcast <- message
  100. }
  101. // BroadcastOthers broadcasts a text message to all sessions except session s.
  102. func (m *Melody) BroadcastOthers(msg []byte, s *Session) {
  103. m.BroadcastFilter(msg, func(q *Session) bool {
  104. return s != q
  105. })
  106. }
  107. // BroadcastBinary broadcasts a binary message to all sessions.
  108. func (m *Melody) BroadcastBinary(msg []byte) {
  109. message := &envelope{t: websocket.BinaryMessage, msg: msg}
  110. m.hub.broadcast <- message
  111. }
  112. // BroadcastBinaryFilter broadcasts a binary message to all sessions that fn returns true for.
  113. func (m *Melody) BroadcastBinaryFilter(msg []byte, fn func(*Session) bool) {
  114. message := &envelope{t: websocket.BinaryMessage, msg: msg, filter: fn}
  115. m.hub.broadcast <- message
  116. }
  117. // BroadcastBinaryOthers broadcasts a binary message to all sessions except session s.
  118. func (m *Melody) BroadcastBinaryOthers(msg []byte, s *Session) {
  119. m.BroadcastBinaryFilter(msg, func(q *Session) bool {
  120. return s != q
  121. })
  122. }
  123. // Close closes the melody instance and all connected sessions.
  124. func (m *Melody) Close() {
  125. m.hub.exit <- true
  126. }