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.

91 lines
1.8 KiB

10 years ago
  1. package melody
  2. import (
  3. "github.com/gorilla/websocket"
  4. "time"
  5. )
  6. type Session struct {
  7. Conn *websocket.Conn
  8. output chan *envelope
  9. config *Config
  10. }
  11. func newSession(config *Config, conn *websocket.Conn) *Session {
  12. return &Session{
  13. Conn: conn,
  14. output: make(chan *envelope, config.MessageBufferSize),
  15. config: config,
  16. }
  17. }
  18. func (s *Session) writeMessage(message *envelope) {
  19. s.output <- message
  20. }
  21. func (s *Session) writeRaw(message *envelope) error {
  22. s.Conn.SetWriteDeadline(time.Now().Add(s.config.WriteWait))
  23. return s.Conn.WriteMessage(message.t, message.msg)
  24. }
  25. func (s *Session) close() {
  26. s.writeRaw(&envelope{t: websocket.CloseMessage, msg: []byte{}})
  27. }
  28. func (s *Session) ping() {
  29. s.writeMessage(&envelope{t: websocket.PingMessage, msg: []byte{}})
  30. }
  31. func (s *Session) writePump(errorHandler handleErrorFunc) {
  32. defer s.Conn.Close()
  33. ticker := time.NewTicker(s.config.PingPeriod)
  34. defer ticker.Stop()
  35. for {
  36. select {
  37. case msg, ok := <-s.output:
  38. if !ok {
  39. s.close()
  40. return
  41. }
  42. if err := s.writeRaw(msg); err != nil {
  43. go errorHandler(s, err)
  44. return
  45. }
  46. case <-ticker.C:
  47. s.ping()
  48. }
  49. }
  50. }
  51. func (s *Session) readPump(messageHandler handleMessageFunc, errorHandler handleErrorFunc) {
  52. defer s.Conn.Close()
  53. s.Conn.SetReadLimit(s.config.MaxMessageSize)
  54. s.Conn.SetReadDeadline(time.Now().Add(s.config.PongWait))
  55. s.Conn.SetPongHandler(func(string) error {
  56. s.Conn.SetReadDeadline(time.Now().Add(s.config.PongWait))
  57. return nil
  58. })
  59. for {
  60. _, message, err := s.Conn.ReadMessage()
  61. if err != nil {
  62. go errorHandler(s, err)
  63. break
  64. }
  65. go messageHandler(s, message)
  66. }
  67. }
  68. func (s *Session) Write(msg []byte) {
  69. s.writeMessage(&envelope{t: websocket.TextMessage, msg: msg})
  70. }
  71. func (s *Session) Close() {
  72. s.writeMessage(&envelope{t: websocket.CloseMessage, msg: []byte{}})
  73. }