From 89e2dbac1504d6df205938df750fa9eb15996afd Mon Sep 17 00:00:00 2001 From: Wim Date: Sat, 11 Mar 2023 18:14:49 +0100 Subject: Check client disconnect to exit for loop (api). Fixes #1983 (#2012) Also update to latest melody upstream --- vendor/gopkg.in/olahol/melody.v1/.gitignore | 5 - vendor/gopkg.in/olahol/melody.v1/.travis.yml | 10 - vendor/gopkg.in/olahol/melody.v1/CHANGELOG.md | 44 ---- vendor/gopkg.in/olahol/melody.v1/LICENSE | 22 -- vendor/gopkg.in/olahol/melody.v1/README.md | 185 --------------- vendor/gopkg.in/olahol/melody.v1/config.go | 22 -- vendor/gopkg.in/olahol/melody.v1/doc.go | 22 -- vendor/gopkg.in/olahol/melody.v1/envelope.go | 7 - vendor/gopkg.in/olahol/melody.v1/hub.go | 80 ------- vendor/gopkg.in/olahol/melody.v1/melody.go | 313 -------------------------- vendor/gopkg.in/olahol/melody.v1/session.go | 219 ------------------ 11 files changed, 929 deletions(-) delete mode 100644 vendor/gopkg.in/olahol/melody.v1/.gitignore delete mode 100644 vendor/gopkg.in/olahol/melody.v1/.travis.yml delete mode 100644 vendor/gopkg.in/olahol/melody.v1/CHANGELOG.md delete mode 100644 vendor/gopkg.in/olahol/melody.v1/LICENSE delete mode 100644 vendor/gopkg.in/olahol/melody.v1/README.md delete mode 100644 vendor/gopkg.in/olahol/melody.v1/config.go delete mode 100644 vendor/gopkg.in/olahol/melody.v1/doc.go delete mode 100644 vendor/gopkg.in/olahol/melody.v1/envelope.go delete mode 100644 vendor/gopkg.in/olahol/melody.v1/hub.go delete mode 100644 vendor/gopkg.in/olahol/melody.v1/melody.go delete mode 100644 vendor/gopkg.in/olahol/melody.v1/session.go (limited to 'vendor/gopkg.in/olahol') diff --git a/vendor/gopkg.in/olahol/melody.v1/.gitignore b/vendor/gopkg.in/olahol/melody.v1/.gitignore deleted file mode 100644 index 31ea56b1..00000000 --- a/vendor/gopkg.in/olahol/melody.v1/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -.DS_Store -benchmark -*.swp -coverage.out -Makefile diff --git a/vendor/gopkg.in/olahol/melody.v1/.travis.yml b/vendor/gopkg.in/olahol/melody.v1/.travis.yml deleted file mode 100644 index f1a141cd..00000000 --- a/vendor/gopkg.in/olahol/melody.v1/.travis.yml +++ /dev/null @@ -1,10 +0,0 @@ -language: go -sudo: required -go: -- 1.6 -- 1.7 -- 1.8 -install: - - go get github.com/gorilla/websocket -script: - - go test diff --git a/vendor/gopkg.in/olahol/melody.v1/CHANGELOG.md b/vendor/gopkg.in/olahol/melody.v1/CHANGELOG.md deleted file mode 100644 index ff511ddd..00000000 --- a/vendor/gopkg.in/olahol/melody.v1/CHANGELOG.md +++ /dev/null @@ -1,44 +0,0 @@ -## 2017-05-18 - -* Fix `HandleSentMessageBinary`. - -## 2017-04-11 - -* Allow any origin by default. -* Add `BroadcastMultiple`. - -## 2017-04-09 - -* Add control message support. -* Add `IsClosed` to Session. - -## 2017-02-10 - -* Return errors for some exposed methods. -* Add `HandleRequestWithKeys`. -* Add `HandleSentMessage` and `HandleSentMessageBinary`. - -## 2017-01-20 - -* Add `Len()` to fetch number of connected sessions. - -## 2016-12-09 - -* Add metadata management for sessions. - -## 2016-05-09 - -* Add method `HandlePong` to melody instance. - -## 2015-10-07 - -* Add broadcast methods for binary messages. - -## 2015-09-03 - -* Add `Close` method to melody instance. - -### 2015-06-10 - -* Support for binary messages. -* BroadcastOthers method. diff --git a/vendor/gopkg.in/olahol/melody.v1/LICENSE b/vendor/gopkg.in/olahol/melody.v1/LICENSE deleted file mode 100644 index 4ae857e8..00000000 --- a/vendor/gopkg.in/olahol/melody.v1/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2015 Ola Holmström. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/gopkg.in/olahol/melody.v1/README.md b/vendor/gopkg.in/olahol/melody.v1/README.md deleted file mode 100644 index 67e3ab50..00000000 --- a/vendor/gopkg.in/olahol/melody.v1/README.md +++ /dev/null @@ -1,185 +0,0 @@ -# melody - -[![Build Status](https://travis-ci.org/olahol/melody.svg)](https://travis-ci.org/olahol/melody) -[![Coverage Status](https://img.shields.io/coveralls/olahol/melody.svg?style=flat)](https://coveralls.io/r/olahol/melody) -[![GoDoc](https://godoc.org/github.com/olahol/melody?status.svg)](https://godoc.org/github.com/olahol/melody) - -> :notes: Minimalist websocket framework for Go. - -Melody is websocket framework based on [github.com/gorilla/websocket](https://github.com/gorilla/websocket) -that abstracts away the tedious parts of handling websockets. It gets out of -your way so you can write real-time apps. Features include: - -* [x] Clear and easy interface similar to `net/http` or Gin. -* [x] A simple way to broadcast to all or selected connected sessions. -* [x] Message buffers making concurrent writing safe. -* [x] Automatic handling of ping/pong and session timeouts. -* [x] Store data on sessions. - -## Install - -```bash -go get gopkg.in/olahol/melody.v1 -``` - -## [Example: chat](https://github.com/olahol/melody/tree/master/examples/chat) - -[![Chat](https://cdn.rawgit.com/olahol/melody/master/examples/chat/demo.gif "Demo")](https://github.com/olahol/melody/tree/master/examples/chat) - -Using [Gin](https://github.com/gin-gonic/gin): -```go -package main - -import ( - "github.com/gin-gonic/gin" - "gopkg.in/olahol/melody.v1" - "net/http" -) - -func main() { - r := gin.Default() - m := melody.New() - - r.GET("/", func(c *gin.Context) { - http.ServeFile(c.Writer, c.Request, "index.html") - }) - - r.GET("/ws", func(c *gin.Context) { - m.HandleRequest(c.Writer, c.Request) - }) - - m.HandleMessage(func(s *melody.Session, msg []byte) { - m.Broadcast(msg) - }) - - r.Run(":5000") -} -``` - -Using [Echo](https://github.com/labstack/echo): -```go -package main - -import ( - "github.com/labstack/echo" - "github.com/labstack/echo/engine/standard" - "github.com/labstack/echo/middleware" - "gopkg.in/olahol/melody.v1" - "net/http" -) - -func main() { - e := echo.New() - m := melody.New() - - e.Use(middleware.Logger()) - e.Use(middleware.Recover()) - - e.GET("/", func(c echo.Context) error { - http.ServeFile(c.Response().(*standard.Response).ResponseWriter, c.Request().(*standard.Request).Request, "index.html") - return nil - }) - - e.GET("/ws", func(c echo.Context) error { - m.HandleRequest(c.Response().(*standard.Response).ResponseWriter, c.Request().(*standard.Request).Request) - return nil - }) - - m.HandleMessage(func(s *melody.Session, msg []byte) { - m.Broadcast(msg) - }) - - e.Run(standard.New(":5000")) -} -``` - -## [Example: gophers](https://github.com/olahol/melody/tree/master/examples/gophers) - -[![Gophers](https://cdn.rawgit.com/olahol/melody/master/examples/gophers/demo.gif "Demo")](https://github.com/olahol/melody/tree/master/examples/gophers) - -```go -package main - -import ( - "github.com/gin-gonic/gin" - "gopkg.in/olahol/melody.v1" - "net/http" - "strconv" - "strings" - "sync" -) - -type GopherInfo struct { - ID, X, Y string -} - -func main() { - router := gin.Default() - mrouter := melody.New() - gophers := make(map[*melody.Session]*GopherInfo) - lock := new(sync.Mutex) - counter := 0 - - router.GET("/", func(c *gin.Context) { - http.ServeFile(c.Writer, c.Request, "index.html") - }) - - router.GET("/ws", func(c *gin.Context) { - mrouter.HandleRequest(c.Writer, c.Request) - }) - - mrouter.HandleConnect(func(s *melody.Session) { - lock.Lock() - for _, info := range gophers { - s.Write([]byte("set " + info.ID + " " + info.X + " " + info.Y)) - } - gophers[s] = &GopherInfo{strconv.Itoa(counter), "0", "0"} - s.Write([]byte("iam " + gophers[s].ID)) - counter += 1 - lock.Unlock() - }) - - mrouter.HandleDisconnect(func(s *melody.Session) { - lock.Lock() - mrouter.BroadcastOthers([]byte("dis "+gophers[s].ID), s) - delete(gophers, s) - lock.Unlock() - }) - - mrouter.HandleMessage(func(s *melody.Session, msg []byte) { - p := strings.Split(string(msg), " ") - lock.Lock() - info := gophers[s] - if len(p) == 2 { - info.X = p[0] - info.Y = p[1] - mrouter.BroadcastOthers([]byte("set "+info.ID+" "+info.X+" "+info.Y), s) - } - lock.Unlock() - }) - - router.Run(":5000") -} -``` - -### [More examples](https://github.com/olahol/melody/tree/master/examples) - -## [Documentation](https://godoc.org/github.com/olahol/melody) - -## Contributors - -* Ola Holmström (@olahol) -* Shogo Iwano (@shiwano) -* Matt Caldwell (@mattcaldwell) -* Heikki Uljas (@huljas) -* Robbie Trencheny (@robbiet480) -* yangjinecho (@yangjinecho) - -## FAQ - -If you are getting a `403` when trying to connect to your websocket you can [change allow all origin hosts](http://godoc.org/github.com/gorilla/websocket#hdr-Origin_Considerations): - -```go -m := melody.New() -m.Upgrader.CheckOrigin = func(r *http.Request) bool { return true } -``` diff --git a/vendor/gopkg.in/olahol/melody.v1/config.go b/vendor/gopkg.in/olahol/melody.v1/config.go deleted file mode 100644 index 81ebd057..00000000 --- a/vendor/gopkg.in/olahol/melody.v1/config.go +++ /dev/null @@ -1,22 +0,0 @@ -package melody - -import "time" - -// Config melody configuration struct. -type Config struct { - WriteWait time.Duration // Milliseconds until write times out. - PongWait time.Duration // Timeout for waiting on pong. - PingPeriod time.Duration // Milliseconds between pings. - MaxMessageSize int64 // Maximum size in bytes of a message. - MessageBufferSize int // The max amount of messages that can be in a sessions buffer before it starts dropping them. -} - -func newConfig() *Config { - return &Config{ - WriteWait: 10 * time.Second, - PongWait: 60 * time.Second, - PingPeriod: (60 * time.Second * 9) / 10, - MaxMessageSize: 512, - MessageBufferSize: 256, - } -} diff --git a/vendor/gopkg.in/olahol/melody.v1/doc.go b/vendor/gopkg.in/olahol/melody.v1/doc.go deleted file mode 100644 index a65aa634..00000000 --- a/vendor/gopkg.in/olahol/melody.v1/doc.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2015 Ola Holmström. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package melody implements a framework for dealing with WebSockets. -// -// Example -// -// A broadcasting echo server: -// -// func main() { -// r := gin.Default() -// m := melody.New() -// r.GET("/ws", func(c *gin.Context) { -// m.HandleRequest(c.Writer, c.Request) -// }) -// m.HandleMessage(func(s *melody.Session, msg []byte) { -// m.Broadcast(msg) -// }) -// r.Run(":5000") -// } -package melody diff --git a/vendor/gopkg.in/olahol/melody.v1/envelope.go b/vendor/gopkg.in/olahol/melody.v1/envelope.go deleted file mode 100644 index baa55a3a..00000000 --- a/vendor/gopkg.in/olahol/melody.v1/envelope.go +++ /dev/null @@ -1,7 +0,0 @@ -package melody - -type envelope struct { - t int - msg []byte - filter filterFunc -} diff --git a/vendor/gopkg.in/olahol/melody.v1/hub.go b/vendor/gopkg.in/olahol/melody.v1/hub.go deleted file mode 100644 index edc6337d..00000000 --- a/vendor/gopkg.in/olahol/melody.v1/hub.go +++ /dev/null @@ -1,80 +0,0 @@ -package melody - -import ( - "sync" -) - -type hub struct { - sessions map[*Session]bool - broadcast chan *envelope - register chan *Session - unregister chan *Session - exit chan *envelope - open bool - rwmutex *sync.RWMutex -} - -func newHub() *hub { - return &hub{ - sessions: make(map[*Session]bool), - broadcast: make(chan *envelope), - register: make(chan *Session), - unregister: make(chan *Session), - exit: make(chan *envelope), - open: true, - rwmutex: &sync.RWMutex{}, - } -} - -func (h *hub) run() { -loop: - for { - select { - case s := <-h.register: - h.rwmutex.Lock() - h.sessions[s] = true - h.rwmutex.Unlock() - case s := <-h.unregister: - if _, ok := h.sessions[s]; ok { - h.rwmutex.Lock() - delete(h.sessions, s) - h.rwmutex.Unlock() - } - case m := <-h.broadcast: - h.rwmutex.RLock() - for s := range h.sessions { - if m.filter != nil { - if m.filter(s) { - s.writeMessage(m) - } - } else { - s.writeMessage(m) - } - } - h.rwmutex.RUnlock() - case m := <-h.exit: - h.rwmutex.Lock() - for s := range h.sessions { - s.writeMessage(m) - delete(h.sessions, s) - s.Close() - } - h.open = false - h.rwmutex.Unlock() - break loop - } - } -} - -func (h *hub) closed() bool { - h.rwmutex.RLock() - defer h.rwmutex.RUnlock() - return !h.open -} - -func (h *hub) len() int { - h.rwmutex.RLock() - defer h.rwmutex.RUnlock() - - return len(h.sessions) -} diff --git a/vendor/gopkg.in/olahol/melody.v1/melody.go b/vendor/gopkg.in/olahol/melody.v1/melody.go deleted file mode 100644 index 6e416b15..00000000 --- a/vendor/gopkg.in/olahol/melody.v1/melody.go +++ /dev/null @@ -1,313 +0,0 @@ -package melody - -import ( - "errors" - "net/http" - "sync" - - "github.com/gorilla/websocket" -) - -// Close codes defined in RFC 6455, section 11.7. -// Duplicate of codes from gorilla/websocket for convenience. -const ( - CloseNormalClosure = 1000 - CloseGoingAway = 1001 - CloseProtocolError = 1002 - CloseUnsupportedData = 1003 - CloseNoStatusReceived = 1005 - CloseAbnormalClosure = 1006 - CloseInvalidFramePayloadData = 1007 - ClosePolicyViolation = 1008 - CloseMessageTooBig = 1009 - CloseMandatoryExtension = 1010 - CloseInternalServerErr = 1011 - CloseServiceRestart = 1012 - CloseTryAgainLater = 1013 - CloseTLSHandshake = 1015 -) - -// Duplicate of codes from gorilla/websocket for convenience. -var validReceivedCloseCodes = map[int]bool{ - // see http://www.iana.org/assignments/websocket/websocket.xhtml#close-code-number - - CloseNormalClosure: true, - CloseGoingAway: true, - CloseProtocolError: true, - CloseUnsupportedData: true, - CloseNoStatusReceived: false, - CloseAbnormalClosure: false, - CloseInvalidFramePayloadData: true, - ClosePolicyViolation: true, - CloseMessageTooBig: true, - CloseMandatoryExtension: true, - CloseInternalServerErr: true, - CloseServiceRestart: true, - CloseTryAgainLater: true, - CloseTLSHandshake: false, -} - -type handleMessageFunc func(*Session, []byte) -type handleErrorFunc func(*Session, error) -type handleCloseFunc func(*Session, int, string) error -type handleSessionFunc func(*Session) -type filterFunc func(*Session) bool - -// Melody implements a websocket manager. -type Melody struct { - Config *Config - Upgrader *websocket.Upgrader - messageHandler handleMessageFunc - messageHandlerBinary handleMessageFunc - messageSentHandler handleMessageFunc - messageSentHandlerBinary handleMessageFunc - errorHandler handleErrorFunc - closeHandler handleCloseFunc - connectHandler handleSessionFunc - disconnectHandler handleSessionFunc - pongHandler handleSessionFunc - hub *hub -} - -// New creates a new melody instance with default Upgrader and Config. -func New() *Melody { - upgrader := &websocket.Upgrader{ - ReadBufferSize: 1024, - WriteBufferSize: 1024, - CheckOrigin: func(r *http.Request) bool { return true }, - } - - hub := newHub() - - go hub.run() - - return &Melody{ - Config: newConfig(), - Upgrader: upgrader, - messageHandler: func(*Session, []byte) {}, - messageHandlerBinary: func(*Session, []byte) {}, - messageSentHandler: func(*Session, []byte) {}, - messageSentHandlerBinary: func(*Session, []byte) {}, - errorHandler: func(*Session, error) {}, - closeHandler: nil, - connectHandler: func(*Session) {}, - disconnectHandler: func(*Session) {}, - pongHandler: func(*Session) {}, - hub: hub, - } -} - -// HandleConnect fires fn when a session connects. -func (m *Melody) HandleConnect(fn func(*Session)) { - m.connectHandler = fn -} - -// HandleDisconnect fires fn when a session disconnects. -func (m *Melody) HandleDisconnect(fn func(*Session)) { - m.disconnectHandler = fn -} - -// HandlePong fires fn when a pong is received from a session. -func (m *Melody) HandlePong(fn func(*Session)) { - m.pongHandler = fn -} - -// HandleMessage fires fn when a text message comes in. -func (m *Melody) HandleMessage(fn func(*Session, []byte)) { - m.messageHandler = fn -} - -// HandleMessageBinary fires fn when a binary message comes in. -func (m *Melody) HandleMessageBinary(fn func(*Session, []byte)) { - m.messageHandlerBinary = fn -} - -// HandleSentMessage fires fn when a text message is successfully sent. -func (m *Melody) HandleSentMessage(fn func(*Session, []byte)) { - m.messageSentHandler = fn -} - -// HandleSentMessageBinary fires fn when a binary message is successfully sent. -func (m *Melody) HandleSentMessageBinary(fn func(*Session, []byte)) { - m.messageSentHandlerBinary = fn -} - -// HandleError fires fn when a session has an error. -func (m *Melody) HandleError(fn func(*Session, error)) { - m.errorHandler = fn -} - -// HandleClose sets the handler for close messages received from the session. -// The code argument to h is the received close code or CloseNoStatusReceived -// if the close message is empty. The default close handler sends a close frame -// back to the session. -// -// The application must read the connection to process close messages as -// described in the section on Control Frames above. -// -// The connection read methods return a CloseError when a close frame is -// received. Most applications should handle close messages as part of their -// normal error handling. Applications should only set a close handler when the -// application must perform some action before sending a close frame back to -// the session. -func (m *Melody) HandleClose(fn func(*Session, int, string) error) { - if fn != nil { - m.closeHandler = fn - } -} - -// HandleRequest upgrades http requests to websocket connections and dispatches them to be handled by the melody instance. -func (m *Melody) HandleRequest(w http.ResponseWriter, r *http.Request) error { - return m.HandleRequestWithKeys(w, r, nil) -} - -// HandleRequestWithKeys does the same as HandleRequest but populates session.Keys with keys. -func (m *Melody) HandleRequestWithKeys(w http.ResponseWriter, r *http.Request, keys map[string]interface{}) error { - if m.hub.closed() { - return errors.New("melody instance is closed") - } - - conn, err := m.Upgrader.Upgrade(w, r, nil) - - if err != nil { - return err - } - - session := &Session{ - Request: r, - Keys: keys, - conn: conn, - output: make(chan *envelope, m.Config.MessageBufferSize), - melody: m, - open: true, - rwmutex: &sync.RWMutex{}, - } - - m.hub.register <- session - - m.connectHandler(session) - - go session.writePump() - - session.readPump() - - if !m.hub.closed() { - m.hub.unregister <- session - } - - session.close() - - m.disconnectHandler(session) - - return nil -} - -// Broadcast broadcasts a text message to all sessions. -func (m *Melody) Broadcast(msg []byte) error { - if m.hub.closed() { - return errors.New("melody instance is closed") - } - - message := &envelope{t: websocket.TextMessage, msg: msg} - m.hub.broadcast <- message - - return nil -} - -// BroadcastFilter broadcasts a text message to all sessions that fn returns true for. -func (m *Melody) BroadcastFilter(msg []byte, fn func(*Session) bool) error { - if m.hub.closed() { - return errors.New("melody instance is closed") - } - - message := &envelope{t: websocket.TextMessage, msg: msg, filter: fn} - m.hub.broadcast <- message - - return nil -} - -// BroadcastOthers broadcasts a text message to all sessions except session s. -func (m *Melody) BroadcastOthers(msg []byte, s *Session) error { - return m.BroadcastFilter(msg, func(q *Session) bool { - return s != q - }) -} - -// BroadcastMultiple broadcasts a text message to multiple sessions given in the sessions slice. -func (m *Melody) BroadcastMultiple(msg []byte, sessions []*Session) error { - for _, sess := range sessions { - if writeErr := sess.Write(msg); writeErr != nil { - return writeErr - } - } - return nil -} - -// BroadcastBinary broadcasts a binary message to all sessions. -func (m *Melody) BroadcastBinary(msg []byte) error { - if m.hub.closed() { - return errors.New("melody instance is closed") - } - - message := &envelope{t: websocket.BinaryMessage, msg: msg} - m.hub.broadcast <- message - - return nil -} - -// BroadcastBinaryFilter broadcasts a binary message to all sessions that fn returns true for. -func (m *Melody) BroadcastBinaryFilter(msg []byte, fn func(*Session) bool) error { - if m.hub.closed() { - return errors.New("melody instance is closed") - } - - message := &envelope{t: websocket.BinaryMessage, msg: msg, filter: fn} - m.hub.broadcast <- message - - return nil -} - -// BroadcastBinaryOthers broadcasts a binary message to all sessions except session s. -func (m *Melody) BroadcastBinaryOthers(msg []byte, s *Session) error { - return m.BroadcastBinaryFilter(msg, func(q *Session) bool { - return s != q - }) -} - -// Close closes the melody instance and all connected sessions. -func (m *Melody) Close() error { - if m.hub.closed() { - return errors.New("melody instance is already closed") - } - - m.hub.exit <- &envelope{t: websocket.CloseMessage, msg: []byte{}} - - return nil -} - -// CloseWithMsg closes the melody instance with the given close payload and all connected sessions. -// Use the FormatCloseMessage function to format a proper close message payload. -func (m *Melody) CloseWithMsg(msg []byte) error { - if m.hub.closed() { - return errors.New("melody instance is already closed") - } - - m.hub.exit <- &envelope{t: websocket.CloseMessage, msg: msg} - - return nil -} - -// Len return the number of connected sessions. -func (m *Melody) Len() int { - return m.hub.len() -} - -// IsClosed returns the status of the melody instance. -func (m *Melody) IsClosed() bool { - return m.hub.closed() -} - -// FormatCloseMessage formats closeCode and text as a WebSocket close message. -func FormatCloseMessage(closeCode int, text string) []byte { - return websocket.FormatCloseMessage(closeCode, text) -} diff --git a/vendor/gopkg.in/olahol/melody.v1/session.go b/vendor/gopkg.in/olahol/melody.v1/session.go deleted file mode 100644 index 3997cefe..00000000 --- a/vendor/gopkg.in/olahol/melody.v1/session.go +++ /dev/null @@ -1,219 +0,0 @@ -package melody - -import ( - "errors" - "net/http" - "sync" - "time" - - "github.com/gorilla/websocket" -) - -// Session wrapper around websocket connections. -type Session struct { - Request *http.Request - Keys map[string]interface{} - conn *websocket.Conn - output chan *envelope - melody *Melody - open bool - rwmutex *sync.RWMutex -} - -func (s *Session) writeMessage(message *envelope) { - if s.closed() { - s.melody.errorHandler(s, errors.New("tried to write to closed a session")) - return - } - - select { - case s.output <- message: - default: - s.melody.errorHandler(s, errors.New("session message buffer is full")) - } -} - -func (s *Session) writeRaw(message *envelope) error { - if s.closed() { - return errors.New("tried to write to a closed session") - } - - s.conn.SetWriteDeadline(time.Now().Add(s.melody.Config.WriteWait)) - err := s.conn.WriteMessage(message.t, message.msg) - - if err != nil { - return err - } - - return nil -} - -func (s *Session) closed() bool { - s.rwmutex.RLock() - defer s.rwmutex.RUnlock() - - return !s.open -} - -func (s *Session) close() { - if !s.closed() { - s.rwmutex.Lock() - s.open = false - s.conn.Close() - close(s.output) - s.rwmutex.Unlock() - } -} - -func (s *Session) ping() { - s.writeRaw(&envelope{t: websocket.PingMessage, msg: []byte{}}) -} - -func (s *Session) writePump() { - ticker := time.NewTicker(s.melody.Config.PingPeriod) - defer ticker.Stop() - -loop: - for { - select { - case msg, ok := <-s.output: - if !ok { - break loop - } - - err := s.writeRaw(msg) - - if err != nil { - s.melody.errorHandler(s, err) - break loop - } - - if msg.t == websocket.CloseMessage { - break loop - } - - if msg.t == websocket.TextMessage { - s.melody.messageSentHandler(s, msg.msg) - } - - if msg.t == websocket.BinaryMessage { - s.melody.messageSentHandlerBinary(s, msg.msg) - } - case <-ticker.C: - s.ping() - } - } -} - -func (s *Session) readPump() { - s.conn.SetReadLimit(s.melody.Config.MaxMessageSize) - s.conn.SetReadDeadline(time.Now().Add(s.melody.Config.PongWait)) - - s.conn.SetPongHandler(func(string) error { - s.conn.SetReadDeadline(time.Now().Add(s.melody.Config.PongWait)) - s.melody.pongHandler(s) - return nil - }) - - if s.melody.closeHandler != nil { - s.conn.SetCloseHandler(func(code int, text string) error { - return s.melody.closeHandler(s, code, text) - }) - } - - for { - t, message, err := s.conn.ReadMessage() - - if err != nil { - s.melody.errorHandler(s, err) - break - } - - if t == websocket.TextMessage { - s.melody.messageHandler(s, message) - } - - if t == websocket.BinaryMessage { - s.melody.messageHandlerBinary(s, message) - } - } -} - -// Write writes message to session. -func (s *Session) Write(msg []byte) error { - if s.closed() { - return errors.New("session is closed") - } - - s.writeMessage(&envelope{t: websocket.TextMessage, msg: msg}) - - return nil -} - -// WriteBinary writes a binary message to session. -func (s *Session) WriteBinary(msg []byte) error { - if s.closed() { - return errors.New("session is closed") - } - - s.writeMessage(&envelope{t: websocket.BinaryMessage, msg: msg}) - - return nil -} - -// Close closes session. -func (s *Session) Close() error { - if s.closed() { - return errors.New("session is already closed") - } - - s.writeMessage(&envelope{t: websocket.CloseMessage, msg: []byte{}}) - - return nil -} - -// CloseWithMsg closes the session with the provided payload. -// Use the FormatCloseMessage function to format a proper close message payload. -func (s *Session) CloseWithMsg(msg []byte) error { - if s.closed() { - return errors.New("session is already closed") - } - - s.writeMessage(&envelope{t: websocket.CloseMessage, msg: msg}) - - return nil -} - -// Set is used to store a new key/value pair exclusivelly for this session. -// It also lazy initializes s.Keys if it was not used previously. -func (s *Session) Set(key string, value interface{}) { - if s.Keys == nil { - s.Keys = make(map[string]interface{}) - } - - s.Keys[key] = value -} - -// Get returns the value for the given key, ie: (value, true). -// If the value does not exists it returns (nil, false) -func (s *Session) Get(key string) (value interface{}, exists bool) { - if s.Keys != nil { - value, exists = s.Keys[key] - } - - return -} - -// MustGet returns the value for the given key if it exists, otherwise it panics. -func (s *Session) MustGet(key string) interface{} { - if value, exists := s.Get(key); exists { - return value - } - - panic("Key \"" + key + "\" does not exist") -} - -// IsClosed returns the status of the connection. -func (s *Session) IsClosed() bool { - return s.closed() -} -- cgit v1.2.3