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.

122 lines
2.4 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
  1. package melody
  2. import (
  3. "github.com/gorilla/websocket"
  4. "net/http"
  5. "time"
  6. )
  7. // A melody session.
  8. type Session struct {
  9. Request *http.Request
  10. conn *websocket.Conn
  11. output chan *envelope
  12. config *Config
  13. }
  14. func newSession(config *Config, conn *websocket.Conn, req *http.Request) *Session {
  15. return &Session{
  16. Request: req,
  17. conn: conn,
  18. output: make(chan *envelope, config.MessageBufferSize),
  19. config: config,
  20. }
  21. }
  22. func (s *Session) writeMessage(message *envelope) {
  23. s.output <- message
  24. }
  25. func (s *Session) writeRaw(message *envelope) error {
  26. s.conn.SetWriteDeadline(time.Now().Add(s.config.WriteWait))
  27. err := s.conn.WriteMessage(message.t, message.msg)
  28. if err != nil {
  29. return err
  30. }
  31. if message.t == websocket.CloseMessage {
  32. err := s.conn.Close()
  33. if err != nil {
  34. return err
  35. }
  36. }
  37. return nil
  38. }
  39. func (s *Session) close() {
  40. s.writeRaw(&envelope{t: websocket.CloseMessage, msg: []byte{}})
  41. }
  42. func (s *Session) ping() {
  43. s.writeMessage(&envelope{t: websocket.PingMessage, msg: []byte{}})
  44. }
  45. func (s *Session) writePump(errorHandler handleErrorFunc) {
  46. defer s.conn.Close()
  47. ticker := time.NewTicker(s.config.PingPeriod)
  48. defer ticker.Stop()
  49. for {
  50. select {
  51. case msg, ok := <-s.output:
  52. if !ok {
  53. s.close()
  54. return
  55. }
  56. if err := s.writeRaw(msg); err != nil {
  57. go errorHandler(s, err)
  58. return
  59. }
  60. case <-ticker.C:
  61. s.ping()
  62. }
  63. }
  64. }
  65. func (s *Session) readPump(messageHandler handleMessageFunc, messageHandlerBinary handleMessageFunc, errorHandler handleErrorFunc) {
  66. defer s.conn.Close()
  67. s.conn.SetReadLimit(s.config.MaxMessageSize)
  68. s.conn.SetReadDeadline(time.Now().Add(s.config.PongWait))
  69. s.conn.SetPongHandler(func(string) error {
  70. s.conn.SetReadDeadline(time.Now().Add(s.config.PongWait))
  71. return nil
  72. })
  73. for {
  74. t, message, err := s.conn.ReadMessage()
  75. if err != nil {
  76. go errorHandler(s, err)
  77. break
  78. }
  79. if t == websocket.TextMessage {
  80. go messageHandler(s, message)
  81. }
  82. if t == websocket.BinaryMessage {
  83. go messageHandlerBinary(s, message)
  84. }
  85. }
  86. }
  87. // Write message to session.
  88. func (s *Session) Write(msg []byte) {
  89. s.writeMessage(&envelope{t: websocket.TextMessage, msg: msg})
  90. }
  91. // Write binary message to session.
  92. func (s *Session) WriteBinary(msg []byte) {
  93. s.writeMessage(&envelope{t: websocket.BinaryMessage, msg: msg})
  94. }
  95. // Close session.
  96. func (s *Session) Close() {
  97. s.writeMessage(&envelope{t: websocket.CloseMessage, msg: []byte{}})
  98. }