func (h *handler) sockjsWebsocket(rw http.ResponseWriter, req *http.Request) { conn, err := websocket.Upgrade(rw, req, nil, WebSocketReadBufSize, WebSocketWriteBufSize) if _, ok := err.(websocket.HandshakeError); ok { http.Error(rw, `Can "Upgrade" only to "WebSocket".`, http.StatusBadRequest) return } else if err != nil { rw.WriteHeader(http.StatusInternalServerError) return } sessID, _ := h.parseSessionID(req.URL) sess := newSession(sessID, h.options.DisconnectDelay, h.options.HeartbeatDelay) if h.handlerFunc != nil { go h.handlerFunc(sess) } receiver := newWsReceiver(conn) sess.attachReceiver(receiver) readCloseCh := make(chan struct{}) go func() { var d []string for { err := conn.ReadJSON(&d) if err != nil { close(readCloseCh) return } sess.accept(d...) } }() select { case <-readCloseCh: case <-receiver.doneNotify(): } sess.close() conn.Close() }
// RawWebsocketHandler called when new client connection comes to raw Websocket endpoint. func (app *Application) RawWebsocketHandler(w http.ResponseWriter, r *http.Request) { ws, err := websocket.Upgrade(w, r, nil, sockjs.WebSocketReadBufSize, sockjs.WebSocketWriteBufSize) if _, ok := err.(websocket.HandshakeError); ok { http.Error(w, `Can "Upgrade" only to "WebSocket".`, http.StatusBadRequest) return } else if err != nil { w.WriteHeader(http.StatusInternalServerError) return } defer ws.Close() conn := wsConn{ ws: ws, } c, err := newClient(app, conn) if err != nil { return } logger.INFO.Printf("New raw Websocket session established with uid %s\n", c.uid()) defer c.clean() for { _, message, err := conn.ws.ReadMessage() if err != nil { break } err = c.message(message) if err != nil { logger.ERROR.Println(err) conn.Close(CloseStatus, "error handling message") break } } }