public override void Callback(Gs2RestResponse gs2RestResponse) { var error = gs2RestResponse.Error; string accessToken = null; if (error == null) { try { accessToken = LoginResult.FromDict(JsonMapper.ToObject(gs2RestResponse.Message)).access_token; } catch (System.Exception) { error = new UnknownException("JSON parsing error: \n" + gs2RestResponse.Message); } } _gs2RestSession.OpenCallback(accessToken, error); }
private WebSocket CreateWebSocket() { var url = EndpointHost.Replace("{region}", Region.DisplayName()); var webSocket = new WebSocket(url) { SslConfiguration = { EnabledSslProtocols = SslProtocols.Tls12, CheckCertificateRevocation = _checkCertificateRevocation } }; webSocket.OnOpen += (sender, eventArgs) => { _state = State.LoggingIn; webSocket.SendAsync( "{" + $"\"client_id\": \"{Credential.ClientId}\"," + $"\"client_secret\": \"{Credential.ClientSecret}\"," + "\"x_gs2\": {" + "\"service\": \"identifier\"," + "\"component\": \"projectToken\"," + "\"function\": \"login\"," + "\"contentType\": \"application/json\"," + $"\"requestId\": \"{Gs2SessionTaskId.LoginId.ToString()}\"" + "}" + "}", null ); }; webSocket.OnMessage += (sender, messageEventArgs) => { if (messageEventArgs.IsText) { var gs2WebSocketResponse = new Gs2WebSocketResponse(messageEventArgs.Data); switch (_state) { case State.LoggingIn: if (gs2WebSocketResponse.Gs2SessionTaskId == Gs2SessionTaskId.LoginId) { if (gs2WebSocketResponse.Error == null) { LoginResult loginResult = LoginResult.FromDict(gs2WebSocketResponse.Body); if (loginResult.access_token != null) { _state = State.Available; OpenCallback(loginResult.access_token, null); } else { _lastGs2Exception = new UnknownException("No project token returned."); _state = State.LoginFailed; webSocket.CloseAsync(); } } else { _lastGs2Exception = gs2WebSocketResponse.Error; _state = State.LoginFailed; webSocket.CloseAsync(); } } break; case State.Available: if (gs2WebSocketResponse.Gs2SessionTaskId == Gs2SessionTaskId.InvalidId) { // API 応答以外のメッセージ OnNotificationMessage?.Invoke( NotificationMessage.FromDict(gs2WebSocketResponse.Body) ); } else { OnMessage(gs2WebSocketResponse.Gs2SessionTaskId, gs2WebSocketResponse); } break; case State.Idle: case State.Opening: case State.LoginFailed: break; } } }; webSocket.OnClose += (sender, closeEventArgs) => { var state = _state; _state = State.Idle; switch (state) { case State.Idle: // 来ない break; case State.Opening: // TODO: OnError を通ってからくるか確認 case State.LoggingIn: case State.LoginFailed: // Gs2Session としては Available になっていないので closeCallback ではなく openCallback に失敗を伝える OpenCallback(null, _lastGs2Exception); break; case State.Available: // 自発的な切断も外部要因による切断もここ CloseCallback(); // TODO: Cancel にわたすエラーを引数に取る break; } }; webSocket.OnError += (sender, errorEventArgs) => { var gs2Exception = new SessionNotOpenException("Session no longer open."); switch (_state) { case State.Idle: // 来ない break; case State.Opening: // この直後に OnClose が呼ばれる _lastGs2Exception = gs2Exception; break; case State.LoggingIn: _lastGs2Exception = gs2Exception; _state = State.LoginFailed; webSocket.CloseAsync(); break; case State.LoginFailed: // 来ないはず break; case State.Available: // 実行中のタスクのどれが失敗したのかわからないので、全部失敗にする // TODO break; } }; return(webSocket); }