private static int AuthCallback(ref ConnectCredential[] creds, IntPtr cbdata) { AuthData authData = (AuthData)Marshal.PtrToStructure(cbdata, typeof(AuthData)); for (int i = 0; i < creds.Length; i++) { ConnectCredential cred = creds[i]; switch (cred.type) { case ConnectCredentialType.VIR_CRED_AUTHNAME: // Fill the user name cred.Result = authData.user_name; break; case ConnectCredentialType.VIR_CRED_PASSPHRASE: // Fill the password cred.Result = authData.password; break; default: return(-1); } } return(0); }
private async Task Reconnect(ConnectCredential reconnectCredential) { if (_isReconnecting) { return; } _isReconnecting = true; int tryNumber = 0; while (true) { try { _logger.LogInformation("Performing reconnect"); await Task.Delay(_reconnectDelay); await Disconnect(); if (reconnectCredential != null) { var subs = _subscriptions.Values.ToArray(); foreach (var sub in subs) { await Remove(sub); sub.RenewId(); await Add(sub); } await Connect(reconnectCredential); } _logger.LogInformation("Reconnected"); break; } catch (Exception ex) { _logger.LogException(ex); if (tryNumber++ >= _maxReconnectsInRow) { _logger.LogInformation("Reconnect stopped"); break; } } } _isReconnecting = false; }
public async Task Connect(ConnectCredential connectCredential) { if (Connected) { _logger.LogWarning("Client already connected"); return; } DisposeClient(); _client = new ClientWebSocket(); var connectTryNumber = 0; while (true) { try { connectTryNumber++; await _client.ConnectAsync(new Uri(connectCredential.Host), CancellationToken.None); break; } catch (Exception ex) { _logger.LogException(ex); if (connectTryNumber > 3) { throw; } } } _logger.LogInformation("Connection established"); var resp = (await Receive()).First().String; _sessionId = GetSession(resp); _logger.LogInformation($"Session established: {_sessionId}"); var connectMessage = new StompMessage(StompMessageCommand.CONNECT, new Headers { ["login"] = connectCredential.Login, ["passcode"] = connectCredential.Passcode, ["domain"] = connectCredential.Domain, ["language"] = "ru", }); await SendMessage(connectMessage); foreach (var message in await ReceiveMessages()) { _logger.LogMessage(message); ThrowOnErrorStompMessage(message); } Connected = true; foreach (var sub in _subscriptions.Values) { await Subscribe(sub); } _receiveLoop = Task.Run(async() => { while (Connected) { if (_client.State == WebSocketState.Open) { try { foreach (var m in await ReceiveMessages()) { _logger.LogMessage(m); ThrowOnErrorStompMessage(m); foreach (var sub in _subscriptions.Values) { await sub.ProcessMessage(m); } } } catch (Exception ex) { var standardClosing = ex is IssPlusWebSocketClientReceiveException && ex.Message == "Tunnel closed"; if (!standardClosing) { _logger.LogException(ex); var _ = Reconnect(connectCredential); return; } } } else { await Task.Delay(1000); } } }); }