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.

145 lines
3.6 KiB

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