diff --git a/config.go b/config.go index 84ae834..f483af1 100644 --- a/config.go +++ b/config.go @@ -2,6 +2,7 @@ package melody import "time" +// Melody configuration, all times in milliseconds. type Config struct { WriteWait time.Duration PongWait time.Duration diff --git a/examples/chat/main.go b/examples/chat/main.go index b136ab9..c3e8c10 100644 --- a/examples/chat/main.go +++ b/examples/chat/main.go @@ -8,7 +8,7 @@ import ( func main() { r := gin.Default() - m := melody.Default() + m := melody.New() r.GET("/", func(c *gin.Context) { http.ServeFile(c.Writer, c.Request, "index.html") diff --git a/examples/filewatch/main.go b/examples/filewatch/main.go index f034293..9f63113 100644 --- a/examples/filewatch/main.go +++ b/examples/filewatch/main.go @@ -12,7 +12,7 @@ func main() { file := "file.txt" r := gin.Default() - m := melody.Default() + m := melody.New() w, _ := fsnotify.NewWatcher() r.GET("/", func(c *gin.Context) { diff --git a/hub.go b/hub.go index 372ca8f..657dbc1 100644 --- a/hub.go +++ b/hub.go @@ -25,7 +25,7 @@ func (h *hub) run() { if _, ok := h.sessions[s]; ok { delete(h.sessions, s) close(s.output) - s.Conn.Close() + s.conn.Close() } case m := <-h.broadcast: for s := range h.sessions { diff --git a/melody.go b/melody.go index 0682d55..ac45bc4 100644 --- a/melody.go +++ b/melody.go @@ -12,15 +12,16 @@ type filterFunc func(*Session) bool type Melody struct { Config *Config - Upgrader *websocket.Upgrader - MessageHandler handleMessageFunc - ErrorHandler handleErrorFunc - ConnectHandler handleSessionFunc - DisconnectHandler handleSessionFunc + upgrader *websocket.Upgrader + messageHandler handleMessageFunc + errorHandler handleErrorFunc + connectHandler handleSessionFunc + disconnectHandler handleSessionFunc hub *hub } -func Default() *Melody { +// Returns a new melody instance. +func New() *Melody { upgrader := &websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, @@ -32,33 +33,38 @@ func Default() *Melody { return &Melody{ Config: newConfig(), - Upgrader: upgrader, - MessageHandler: func(*Session, []byte) {}, - ErrorHandler: func(*Session, error) {}, - ConnectHandler: func(*Session) {}, - DisconnectHandler: func(*Session) {}, + upgrader: upgrader, + messageHandler: func(*Session, []byte) {}, + errorHandler: func(*Session, error) {}, + connectHandler: func(*Session) {}, + disconnectHandler: func(*Session) {}, hub: hub, } } -func (m *Melody) HandleConnect(fn handleSessionFunc) { - m.ConnectHandler = fn +// Fires fn when a session connects. +func (m *Melody) HandleConnect(fn func(*Session)) { + m.connectHandler = fn } -func (m *Melody) HandleDisconnect(fn handleSessionFunc) { - m.DisconnectHandler = fn +// Fires fn when a session disconnects. +func (m *Melody) HandleDisconnect(fn func(*Session)) { + m.disconnectHandler = fn } -func (m *Melody) HandleMessage(fn handleMessageFunc) { - m.MessageHandler = fn +// Callback when a message comes in. +func (m *Melody) HandleMessage(fn func(*Session, []byte)) { + m.messageHandler = fn } +// Fires when a session has an error. func (m *Melody) HandleError(fn handleErrorFunc) { - m.ErrorHandler = fn + m.errorHandler = fn } +// Handles a http request and upgrades it to a websocket. func (m *Melody) HandleRequest(w http.ResponseWriter, r *http.Request) error { - conn, err := m.Upgrader.Upgrade(w, r, nil) + conn, err := m.upgrader.Upgrade(w, r, nil) if err != nil { return err @@ -68,25 +74,27 @@ func (m *Melody) HandleRequest(w http.ResponseWriter, r *http.Request) error { m.hub.register <- session - go m.ConnectHandler(session) + go m.connectHandler(session) - go session.writePump(m.ErrorHandler) + go session.writePump(m.errorHandler) - session.readPump(m.MessageHandler, m.ErrorHandler) + session.readPump(m.messageHandler, m.errorHandler) m.hub.unregister <- session - go m.DisconnectHandler(session) + go m.disconnectHandler(session) return nil } +// Broadcasts a message to all sessions. func (m *Melody) Broadcast(msg []byte) { message := &envelope{t: websocket.TextMessage, msg: msg} m.hub.broadcast <- message } -func (m *Melody) BroadcastFilter(fn filterFunc, msg []byte) { +// Broadcasts a message to all sessions that fn returns true for. +func (m *Melody) BroadcastFilter(fn func(*Session) bool, msg []byte) { message := &envelope{t: websocket.TextMessage, msg: msg, filter: fn} m.hub.broadcast <- message } diff --git a/melody_test.go b/melody_test.go index b692b46..0b6557a 100644 --- a/melody_test.go +++ b/melody_test.go @@ -15,7 +15,7 @@ type TestServer struct { } func NewTestServerHandler(handler handleMessageFunc) *TestServer { - m := Default() + m := New() m.HandleMessage(handler) return &TestServer{ m: m, @@ -23,7 +23,7 @@ func NewTestServerHandler(handler handleMessageFunc) *TestServer { } func NewTestServer() *TestServer { - m := Default() + m := New() return &TestServer{ m: m, } diff --git a/session.go b/session.go index b12847b..fb7eeb4 100644 --- a/session.go +++ b/session.go @@ -5,15 +5,16 @@ import ( "time" ) +// A melody session. type Session struct { - Conn *websocket.Conn + conn *websocket.Conn output chan *envelope config *Config } func newSession(config *Config, conn *websocket.Conn) *Session { return &Session{ - Conn: conn, + conn: conn, output: make(chan *envelope, config.MessageBufferSize), config: config, } @@ -24,8 +25,8 @@ func (s *Session) writeMessage(message *envelope) { } func (s *Session) writeRaw(message *envelope) error { - s.Conn.SetWriteDeadline(time.Now().Add(s.config.WriteWait)) - return s.Conn.WriteMessage(message.t, message.msg) + s.conn.SetWriteDeadline(time.Now().Add(s.config.WriteWait)) + return s.conn.WriteMessage(message.t, message.msg) } func (s *Session) close() { @@ -37,7 +38,7 @@ func (s *Session) ping() { } func (s *Session) writePump(errorHandler handleErrorFunc) { - defer s.Conn.Close() + defer s.conn.Close() ticker := time.NewTicker(s.config.PingPeriod) defer ticker.Stop() @@ -60,18 +61,18 @@ func (s *Session) writePump(errorHandler handleErrorFunc) { } func (s *Session) readPump(messageHandler handleMessageFunc, errorHandler handleErrorFunc) { - defer s.Conn.Close() + defer s.conn.Close() - s.Conn.SetReadLimit(s.config.MaxMessageSize) - s.Conn.SetReadDeadline(time.Now().Add(s.config.PongWait)) + s.conn.SetReadLimit(s.config.MaxMessageSize) + s.conn.SetReadDeadline(time.Now().Add(s.config.PongWait)) - s.Conn.SetPongHandler(func(string) error { - s.Conn.SetReadDeadline(time.Now().Add(s.config.PongWait)) + s.conn.SetPongHandler(func(string) error { + s.conn.SetReadDeadline(time.Now().Add(s.config.PongWait)) return nil }) for { - _, message, err := s.Conn.ReadMessage() + _, message, err := s.conn.ReadMessage() if err != nil { go errorHandler(s, err) @@ -82,10 +83,12 @@ func (s *Session) readPump(messageHandler handleMessageFunc, errorHandler handle } } +// Write a message to session. func (s *Session) Write(msg []byte) { s.writeMessage(&envelope{t: websocket.TextMessage, msg: msg}) } +// Close a session. func (s *Session) Close() { s.writeMessage(&envelope{t: websocket.CloseMessage, msg: []byte{}}) }