diff options
Diffstat (limited to 'cmd/dolmetschctld/web_socket.go')
-rw-r--r-- | cmd/dolmetschctld/web_socket.go | 64 |
1 files changed, 37 insertions, 27 deletions
diff --git a/cmd/dolmetschctld/web_socket.go b/cmd/dolmetschctld/web_socket.go index 09f2efc..dcbb311 100644 --- a/cmd/dolmetschctld/web_socket.go +++ b/cmd/dolmetschctld/web_socket.go @@ -47,74 +47,83 @@ func sendWebSocketErrorResponse(ws *websocket.Conn, code int, errStr string) { sendWebSocketResponse(ws, rd) } -func webSocketHandleRequest(ws *websocket.Conn, sm *StateMachine, req types.WebSocketRequest, subCh chan<- types.FullState) { +type webSocketSession struct { + ws *websocket.Conn + sm *StateMachine + stateSubCh chan types.FullState + stateUnsubCh chan<- struct{} +} + +func (s *webSocketSession) handleRequest(req types.WebSocketRequest) { switch req.Command { case "state": if len(req.Args) != 0 { - sendWebSocketErrorResponse(ws, http.StatusBadRequest, "command 'state' expects no arguments") + sendWebSocketErrorResponse(s.ws, http.StatusBadRequest, "command 'state' expects no arguments") return } var result types.WebSocketResponseState result.ResponseCode = http.StatusOK result.Type = "state" - result.State, result.Ratio, result.Lang = sm.GetState() - sendWebSocketResponse(ws, result) + result.State, result.Ratio, result.Lang = s.sm.GetState() + sendWebSocketResponse(s.ws, result) case "subscribe": if len(req.Args) != 0 { - sendWebSocketErrorResponse(ws, http.StatusBadRequest, "command 'subscribe' expects no arguments") + sendWebSocketErrorResponse(s.ws, http.StatusBadRequest, "command 'subscribe' expects no arguments") return } - if err := sm.SubscribeState(subCh); err != nil { - sendWebSocketErrorResponse(ws, http.StatusInternalServerError, err.Error()) - return - } + s.stateUnsubCh = s.sm.SubscribeState(s.stateSubCh) var result types.WebSocketResponseState result.ResponseCode = http.StatusOK result.Type = "state" - result.State, result.Ratio, result.Lang = sm.GetState() - sendWebSocketResponse(ws, result) + result.State, result.Ratio, result.Lang = s.sm.GetState() + sendWebSocketResponse(s.ws, result) case "languages": if len(req.Args) != 0 { - sendWebSocketErrorResponse(ws, http.StatusBadRequest, "command 'languages' expects no arguments") + sendWebSocketErrorResponse(s.ws, http.StatusBadRequest, "command 'languages' expects no arguments") return } var result types.WebSocketResponseLanguages result.ResponseCode = http.StatusOK result.Type = "languages" - result.Languages = sm.GetLanguages() - sendWebSocketResponse(ws, result) + result.Languages = s.sm.GetLanguages() + sendWebSocketResponse(s.ws, result) case "language": if len(req.Args) != 1 { - sendWebSocketErrorResponse(ws, http.StatusBadRequest, "command 'language' expects exatly one argument") + sendWebSocketErrorResponse(s.ws, http.StatusBadRequest, "command 'language' expects exatly one argument") return } - if err := sm.SetLanguage(types.Language(req.Args[0])); err != nil { - sendWebSocketErrorResponse(ws, http.StatusBadRequest, err.Error()) + if err := s.sm.SetLanguage(types.Language(req.Args[0])); err != nil { + sendWebSocketErrorResponse(s.ws, http.StatusBadRequest, err.Error()) return } var result types.WebSocketResponseState result.ResponseCode = http.StatusOK result.Type = "state" - result.State, result.Ratio, result.Lang = sm.GetState() - sendWebSocketResponse(ws, result) + result.State, result.Ratio, result.Lang = s.sm.GetState() + sendWebSocketResponse(s.ws, result) default: - sendWebSocketErrorResponse(ws, http.StatusBadRequest, "unkown command: '"+req.Command+"'") + sendWebSocketErrorResponse(s.ws, http.StatusBadRequest, "unkown command: '"+req.Command+"'") } } -func webSocketSessionHandler(ws *websocket.Conn, sm *StateMachine, reqCh <-chan types.WebSocketRequest) { - defer ws.Close() +func (s *webSocketSession) Handler(reqCh <-chan types.WebSocketRequest) { + defer func() { + s.ws.Close() + if s.stateUnsubCh != nil { + close(s.stateUnsubCh) + } + }() - subCh := make(chan types.FullState, 100) + s.stateSubCh = make(chan types.FullState, 100) for { select { - case state, ok := <-subCh: + case state, ok := <-s.stateSubCh: if !ok { return } @@ -124,12 +133,12 @@ func webSocketSessionHandler(ws *websocket.Conn, sm *StateMachine, reqCh <-chan result.State = state.State result.Ratio = state.Ratio result.Lang = state.Language - sendWebSocketResponse(ws, result) + sendWebSocketResponse(s.ws, result) case req, ok := <-reqCh: if !ok { return } - webSocketHandleRequest(ws, sm, req, subCh) + s.handleRequest(req) } } } @@ -145,7 +154,8 @@ func webSocketHandler(sm *StateMachine, w http.ResponseWriter, r *http.Request) } log.Println("Web(socket) client", ws.RemoteAddr(), "connected") reqCh := make(chan types.WebSocketRequest) - go webSocketSessionHandler(ws, sm, reqCh) + session := webSocketSession{ws: ws, sm: sm} + go session.Handler(reqCh) defer close(reqCh) for { |