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.

152 lines
4.1 KiB

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