iris/websocket.go
Gerasimos (Makis) Maropoulos 8bbd9f8fc5 Happy new year! Update to 6.0.0 | HTTP/2 full support. https://github.com/kataras/iris/issues/565
full commit from development branch.

Examples, book, middleware, plugins are updated to the latest iris
version. Read HISTORY.md for more.

The 'old' v5 branch which relied on fasthttp exists for those who want
to use it navigate there: https://github.com/kataras/iris/tree/5.0.0
2017-01-02 21:20:17 +02:00

102 lines
3.3 KiB
Go

package iris
import (
"net/http"
"sync"
"github.com/kataras/go-websocket"
)
// conversionals
const (
// All is the string which the Emmiter use to send a message to all
All = websocket.All
// NotMe is the string which the Emmiter use to send a message to all except this websocket.Connection
NotMe = websocket.NotMe
// Broadcast is the string which the Emmiter use to send a message to all except this websocket.Connection, same as 'NotMe'
Broadcast = websocket.Broadcast
)
// Note I keep this code only to no change the front-end API, we could only use the go-websocket and set our custom upgrader
type (
// WebsocketServer is the iris websocket server, expose the websocket.Server
// the below code is a wrapper and bridge between iris-contrib/websocket and kataras/go-websocket
WebsocketServer struct {
websocket.Server
station *Framework
once sync.Once
// Config:
// if endpoint is not empty then this configuration is used instead of the station's
// useful when the user/dev wants more than one websocket server inside one iris instance.
Config WebsocketConfiguration
}
)
// NewWebsocketServer returns a new empty unitialized websocket server
// it runs on first OnConnection
func NewWebsocketServer(station *Framework) *WebsocketServer {
return &WebsocketServer{station: station, Server: websocket.New()}
}
// NewWebsocketServer creates the client side source route and the route path Endpoint with the correct Handler
// receives the websocket configuration and the iris station
// and returns the websocket server which can be attached to more than one iris station (if needed)
func (ws *WebsocketServer) init() {
if ws.Config.Endpoint == "" {
ws.Config = ws.station.Config.Websocket
}
c := ws.Config
if c.Endpoint == "" {
return
}
// set the routing for client-side source (javascript) (optional)
clientSideLookupName := "iris-websocket-client-side"
ws.station.Get(c.Endpoint, ToHandler(ws.Server.Handler()))
// check if client side already exists
if ws.station.Lookup(clientSideLookupName) == nil {
// serve the client side on domain:port/iris-ws.js
ws.station.StaticContent("/iris-ws.js", contentJavascript, websocket.ClientSource)(clientSideLookupName)
}
if c.CheckOrigin == nil {
c.CheckOrigin = DefaultWebsocketCheckOrigin
}
if c.Error == nil {
c.Error = DefaultWebsocketError
}
// set the underline websocket server's configuration
ws.Server.Set(websocket.Config{
WriteTimeout: c.WriteTimeout,
PongTimeout: c.PongTimeout,
PingPeriod: c.PingPeriod,
MaxMessageSize: c.MaxMessageSize,
BinaryMessages: c.BinaryMessages,
ReadBufferSize: c.ReadBufferSize,
WriteBufferSize: c.WriteBufferSize,
Error: func(w http.ResponseWriter, r *http.Request, status int, reason error) {
ctx := ws.station.AcquireCtx(w, r)
c.Error(ctx, status, reason)
ws.station.ReleaseCtx(ctx)
},
CheckOrigin: c.CheckOrigin,
})
}
// WebsocketConnection is the front-end API that you will use to communicate with the client side
type WebsocketConnection interface {
websocket.Connection
}
// OnConnection this is the main event you, as developer, will work with each of the websocket connections
func (ws *WebsocketServer) OnConnection(connectionListener func(WebsocketConnection)) {
ws.once.Do(ws.init)
ws.Server.OnConnection(func(c websocket.Connection) {
connectionListener(c)
})
}