iris/websocket.go
Gerasimos Maropoulos bffd2074eb Update to 4.4.7
2016-10-05 13:21:40 +03:00

111 lines
4.2 KiB
Go

package iris
import (
irisWebsocket "github.com/iris-contrib/websocket"
"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
upgrader irisWebsocket.Upgrader
}
)
// NewWebsocketServer returns an empty WebsocketServer, nothing special here.
func NewWebsocketServer() *WebsocketServer {
return &WebsocketServer{}
}
// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
//
// The responseHeader is included in the response to the client's upgrade
// request. Use the responseHeader to specify cookies (Set-Cookie) and the
// application negotiated subprotocol (Sec-Websocket-Protocol).
//
// If the upgrade fails, then Upgrade replies to the client with an HTTP error
// response.
func (s *WebsocketServer) Upgrade(ctx *Context) error {
return s.upgrader.Upgrade(ctx)
}
// Handler is the iris Handler to upgrade the request
// used inside RegisterRoutes
func (s *WebsocketServer) Handler(ctx *Context) {
if err := s.Upgrade(ctx); err != nil {
if ctx.framework.Config.IsDevelopment {
ctx.Log("Websocket error while trying to Upgrade the connection. Trace: %s", err.Error())
}
ctx.EmitError(StatusBadRequest)
}
}
// RegisterTo creates the client side source route and the route path Endpoint with the correct Handler
// receives the websocket configuration and the iris station
func (s *WebsocketServer) RegisterTo(station *Framework, c WebsocketConfiguration) {
// Note: s.Server should be initialize on the first OnConnection, which is called before this func when Default websocket server.
// When not: when calling this function before OnConnection, when we have more than one websocket server running
if s.Server == nil {
s.Server = websocket.New()
}
// is just a conversional type for kataras/go-websocket.Connection
s.upgrader = irisWebsocket.Custom(s.Server.HandleConnection, c.ReadBufferSize, c.WriteBufferSize, false)
// set the routing for client-side source (javascript) (optional)
clientSideLookupName := "iris-websocket-client-side"
station.Get(c.Endpoint, s.Handler)
// check if client side already exists
if station.Lookup(clientSideLookupName) == nil {
// serve the client side on domain:port/iris-ws.js
station.StaticContent("/iris-ws.js", contentJavascript, websocket.ClientSource)(clientSideLookupName)
}
s.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,
})
// run the ws server
s.Server.Serve()
}
// 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 (s *WebsocketServer) OnConnection(connectionListener func(WebsocketConnection)) {
if s.Server == nil {
// for default webserver this is the time when the websocket server will be init
// let's initialize here the ws server, the user/dev is free to change its config before this step.
s.Server = websocket.New() // we need that in order to use the Iris' WebsocketConnnection, which
// config is empty here because are setted on the RegisterTo
// websocket's configuration is optional on New because it doesn't really used before the websocket.Serve
}
s.Server.OnConnection(func(c websocket.Connection) {
connectionListener(c)
})
}