documentation
This commit is contained in:
@@ -2,6 +2,7 @@ package melody
|
|||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
|
// Melody configuration, all times in milliseconds.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
WriteWait time.Duration
|
WriteWait time.Duration
|
||||||
PongWait time.Duration
|
PongWait time.Duration
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
m := melody.Default()
|
m := melody.New()
|
||||||
|
|
||||||
r.GET("/", func(c *gin.Context) {
|
r.GET("/", func(c *gin.Context) {
|
||||||
http.ServeFile(c.Writer, c.Request, "index.html")
|
http.ServeFile(c.Writer, c.Request, "index.html")
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ func main() {
|
|||||||
file := "file.txt"
|
file := "file.txt"
|
||||||
|
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
m := melody.Default()
|
m := melody.New()
|
||||||
w, _ := fsnotify.NewWatcher()
|
w, _ := fsnotify.NewWatcher()
|
||||||
|
|
||||||
r.GET("/", func(c *gin.Context) {
|
r.GET("/", func(c *gin.Context) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ func (h *hub) run() {
|
|||||||
if _, ok := h.sessions[s]; ok {
|
if _, ok := h.sessions[s]; ok {
|
||||||
delete(h.sessions, s)
|
delete(h.sessions, s)
|
||||||
close(s.output)
|
close(s.output)
|
||||||
s.Conn.Close()
|
s.conn.Close()
|
||||||
}
|
}
|
||||||
case m := <-h.broadcast:
|
case m := <-h.broadcast:
|
||||||
for s := range h.sessions {
|
for s := range h.sessions {
|
||||||
|
|||||||
@@ -12,15 +12,16 @@ type filterFunc func(*Session) bool
|
|||||||
|
|
||||||
type Melody struct {
|
type Melody struct {
|
||||||
Config *Config
|
Config *Config
|
||||||
Upgrader *websocket.Upgrader
|
upgrader *websocket.Upgrader
|
||||||
MessageHandler handleMessageFunc
|
messageHandler handleMessageFunc
|
||||||
ErrorHandler handleErrorFunc
|
errorHandler handleErrorFunc
|
||||||
ConnectHandler handleSessionFunc
|
connectHandler handleSessionFunc
|
||||||
DisconnectHandler handleSessionFunc
|
disconnectHandler handleSessionFunc
|
||||||
hub *hub
|
hub *hub
|
||||||
}
|
}
|
||||||
|
|
||||||
func Default() *Melody {
|
// Returns a new melody instance.
|
||||||
|
func New() *Melody {
|
||||||
upgrader := &websocket.Upgrader{
|
upgrader := &websocket.Upgrader{
|
||||||
ReadBufferSize: 1024,
|
ReadBufferSize: 1024,
|
||||||
WriteBufferSize: 1024,
|
WriteBufferSize: 1024,
|
||||||
@@ -32,33 +33,38 @@ func Default() *Melody {
|
|||||||
|
|
||||||
return &Melody{
|
return &Melody{
|
||||||
Config: newConfig(),
|
Config: newConfig(),
|
||||||
Upgrader: upgrader,
|
upgrader: upgrader,
|
||||||
MessageHandler: func(*Session, []byte) {},
|
messageHandler: func(*Session, []byte) {},
|
||||||
ErrorHandler: func(*Session, error) {},
|
errorHandler: func(*Session, error) {},
|
||||||
ConnectHandler: func(*Session) {},
|
connectHandler: func(*Session) {},
|
||||||
DisconnectHandler: func(*Session) {},
|
disconnectHandler: func(*Session) {},
|
||||||
hub: hub,
|
hub: hub,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Melody) HandleConnect(fn handleSessionFunc) {
|
// Fires fn when a session connects.
|
||||||
m.ConnectHandler = fn
|
func (m *Melody) HandleConnect(fn func(*Session)) {
|
||||||
|
m.connectHandler = fn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Melody) HandleDisconnect(fn handleSessionFunc) {
|
// Fires fn when a session disconnects.
|
||||||
m.DisconnectHandler = fn
|
func (m *Melody) HandleDisconnect(fn func(*Session)) {
|
||||||
|
m.disconnectHandler = fn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Melody) HandleMessage(fn handleMessageFunc) {
|
// Callback when a message comes in.
|
||||||
m.MessageHandler = fn
|
func (m *Melody) HandleMessage(fn func(*Session, []byte)) {
|
||||||
|
m.messageHandler = fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fires when a session has an error.
|
||||||
func (m *Melody) HandleError(fn handleErrorFunc) {
|
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 {
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -68,25 +74,27 @@ func (m *Melody) HandleRequest(w http.ResponseWriter, r *http.Request) error {
|
|||||||
|
|
||||||
m.hub.register <- session
|
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
|
m.hub.unregister <- session
|
||||||
|
|
||||||
go m.DisconnectHandler(session)
|
go m.disconnectHandler(session)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Broadcasts a message to all sessions.
|
||||||
func (m *Melody) Broadcast(msg []byte) {
|
func (m *Melody) Broadcast(msg []byte) {
|
||||||
message := &envelope{t: websocket.TextMessage, msg: msg}
|
message := &envelope{t: websocket.TextMessage, msg: msg}
|
||||||
m.hub.broadcast <- message
|
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}
|
message := &envelope{t: websocket.TextMessage, msg: msg, filter: fn}
|
||||||
m.hub.broadcast <- message
|
m.hub.broadcast <- message
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -15,7 +15,7 @@ type TestServer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewTestServerHandler(handler handleMessageFunc) *TestServer {
|
func NewTestServerHandler(handler handleMessageFunc) *TestServer {
|
||||||
m := Default()
|
m := New()
|
||||||
m.HandleMessage(handler)
|
m.HandleMessage(handler)
|
||||||
return &TestServer{
|
return &TestServer{
|
||||||
m: m,
|
m: m,
|
||||||
@@ -23,7 +23,7 @@ func NewTestServerHandler(handler handleMessageFunc) *TestServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewTestServer() *TestServer {
|
func NewTestServer() *TestServer {
|
||||||
m := Default()
|
m := New()
|
||||||
return &TestServer{
|
return &TestServer{
|
||||||
m: m,
|
m: m,
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-11
@@ -5,15 +5,16 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// A melody session.
|
||||||
type Session struct {
|
type Session struct {
|
||||||
Conn *websocket.Conn
|
conn *websocket.Conn
|
||||||
output chan *envelope
|
output chan *envelope
|
||||||
config *Config
|
config *Config
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSession(config *Config, conn *websocket.Conn) *Session {
|
func newSession(config *Config, conn *websocket.Conn) *Session {
|
||||||
return &Session{
|
return &Session{
|
||||||
Conn: conn,
|
conn: conn,
|
||||||
output: make(chan *envelope, config.MessageBufferSize),
|
output: make(chan *envelope, config.MessageBufferSize),
|
||||||
config: config,
|
config: config,
|
||||||
}
|
}
|
||||||
@@ -24,8 +25,8 @@ func (s *Session) writeMessage(message *envelope) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) writeRaw(message *envelope) error {
|
func (s *Session) writeRaw(message *envelope) error {
|
||||||
s.Conn.SetWriteDeadline(time.Now().Add(s.config.WriteWait))
|
s.conn.SetWriteDeadline(time.Now().Add(s.config.WriteWait))
|
||||||
return s.Conn.WriteMessage(message.t, message.msg)
|
return s.conn.WriteMessage(message.t, message.msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) close() {
|
func (s *Session) close() {
|
||||||
@@ -37,7 +38,7 @@ func (s *Session) ping() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) writePump(errorHandler handleErrorFunc) {
|
func (s *Session) writePump(errorHandler handleErrorFunc) {
|
||||||
defer s.Conn.Close()
|
defer s.conn.Close()
|
||||||
|
|
||||||
ticker := time.NewTicker(s.config.PingPeriod)
|
ticker := time.NewTicker(s.config.PingPeriod)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
@@ -60,18 +61,18 @@ func (s *Session) writePump(errorHandler handleErrorFunc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) readPump(messageHandler handleMessageFunc, 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.SetReadLimit(s.config.MaxMessageSize)
|
||||||
s.Conn.SetReadDeadline(time.Now().Add(s.config.PongWait))
|
s.conn.SetReadDeadline(time.Now().Add(s.config.PongWait))
|
||||||
|
|
||||||
s.Conn.SetPongHandler(func(string) error {
|
s.conn.SetPongHandler(func(string) error {
|
||||||
s.Conn.SetReadDeadline(time.Now().Add(s.config.PongWait))
|
s.conn.SetReadDeadline(time.Now().Add(s.config.PongWait))
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
for {
|
for {
|
||||||
_, message, err := s.Conn.ReadMessage()
|
_, message, err := s.conn.ReadMessage()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
go errorHandler(s, err)
|
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) {
|
func (s *Session) Write(msg []byte) {
|
||||||
s.writeMessage(&envelope{t: websocket.TextMessage, msg: msg})
|
s.writeMessage(&envelope{t: websocket.TextMessage, msg: msg})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close a session.
|
||||||
func (s *Session) Close() {
|
func (s *Session) Close() {
|
||||||
s.writeMessage(&envelope{t: websocket.CloseMessage, msg: []byte{}})
|
s.writeMessage(&envelope{t: websocket.CloseMessage, msg: []byte{}})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user