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, IDGenerator: c.IDGenerator, }) } // 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) }) }