Esempio n. 1
0
        public override async Task Start()
        {
            while (false == stopper.IsCancellationRequested)
            {
                ClientWebSocket?webSocket = null;
                try {
                    webSocket = new ClientWebSocket();
                    auth.Authenticate(webSocket);
                    await webSocket.ConnectAsync(new Uri(ServerUrl), stopper.Token);

                    Log.Debug($"Connection to server established");
                    serverInfo = RpcPeerInfo.Server(ServerUrl);
                    var connection = new WebSocketRpcConnection(serverInfo, webSocket);
                    channel = await RpcChannel.Create(serverInfo, connection, this, Settings.Backlog);

                    await channel.Start();

                    Log.Debug($"Connection to server closed");
                } catch (Exception ex) {
                    if ((ex as WebSocketException)?.Message.Contains("401") ?? false)
                    {
                        Log.Debug($"Connection to server denied: Unauthorized");
                    }
                    else if (ex is WebSocketException wsEx)
                    {
                        Log.Debug($"Connection to server unexpectedly closed: " + wsEx.WebSocketErrorCode);
                    }
                    else
                    {
                        Log.Debug($"Connection to server unexpectedly closed: " + ex.Message);
                    }
                } finally {
                    webSocket?.Dispose();
                }

                if (false == stopper.IsCancellationRequested)
                {
                    // Reconnect
                    Log.Info($"Trying to reconnect after {Settings.ReconnectTimeMs} ms");
                    await Task.Delay(Settings.ReconnectTimeMs);

                    if (Settings.ReconnectTimeMs >= 30_000) // Repeat logging after a long pause
                    {
                        Log.Info($"Trying to reconnect now");
                    }
                }
            }
        }
Esempio n. 2
0
        private async Task ProcessClient(HttpListenerContext httpContext)
        {
            string ip = httpContext.GetIP();

            // Check authentication
            var authResult = auth.Authenticate(httpContext.Request);

            if (false == authResult.Success || authResult.ClientID == null)
            {
                Log.Debug($"Connection from {ip} denied" +
                          (authResult.ClientID != null ? $" (client ID {authResult.ClientID})" : ""));
                httpContext.Close(HttpStatusCode.Unauthorized);
                return;
            }
            string clientID = authResult.ClientID;

            // Accept web socket
            var clientInfo = RpcPeerInfo.Client(clientID, ip);
            WebSocketContext context;

            try {
                context = await httpContext.AcceptWebSocketAsync(subProtocol : null);

                Log.Debug($"Connected {clientInfo}");
            } catch (Exception ex) {
                Log.Debug($"Could not accept WebSocket to {clientInfo}: {ex.Message}");
                httpContext.Close(HttpStatusCode.InternalServerError);
                return;
            }

            // WebSocket loop
            WebSocket webSocket = context.WebSocket;

            try {
                var connection = new WebSocketRpcConnection(clientInfo, webSocket);
                var channel    = await RpcChannel.Create(clientInfo, connection, this, Settings.Backlog);

                if (channelsByClientID.TryGetValue(clientID, out var oldChannel))
                {
                    Log.Debug($"Channel for client {clientID} was already open; close it and open a new one after 3 seconds.");
                    oldChannel.Stop();
                    await Task.Delay(3000);
                }
                channelsByClientID[clientID] = channel;
                await channel.Start();

                Log.Debug($"Connection to {clientInfo} closed");
            } catch (Exception ex) {
                if (ex is WebSocketException wsEx)
                {
                    Log.Debug($"Connection to {clientInfo} unexpectedly closed: " + wsEx.WebSocketErrorCode);
                }
                else
                {
                    Log.Debug($"Connection to {clientInfo} unexpectedly closed: " + ex.Message);
                }
            } finally {
                webSocket?.Dispose();
            }
            channelsByClientID.Remove(clientID);
        }