/// <summary> /// Called when the adapter is connecting. /// </summary> /// <returns></returns> protected override Task OnConnect() { TaskCompletionSource <object> source = new TaskCompletionSource <object>(); ThreadFactory.StartNew(() => { try { if (_serialPort != null) { _serialPort.DataReceived -= OnSerialPortDataReceived; } _serialPort = new SerialPort(); _serialPort.BaudRate = BaudRate; _serialPort.PortName = Port; _serialPort.ReadBufferSize = MaxBufferSize; _serialPort.WriteBufferSize = MaxBufferSize; _serialPort.Open(); _serialPort.DiscardInBuffer(); _serialPort.DiscardOutBuffer(); _serialPort.DataReceived += OnSerialPortDataReceived; if (!source.Task.IsCompleted) { source.SetResult(true); } } catch (Exception ex) { if (!source.Task.IsCompleted) { source.SetException(ex); } } }); TimeoutTask.StartNew(() => { if (!source.Task.IsCompleted) { source.SetException(Logger.LogErrorThrow(new IOException($"The serial port seems to be in a froze state. Reinitialize the port and try again."))); } }, TimeSpan.FromSeconds(5)); return(source.Task); }
/// <summary> /// Called when the adapter is disconnecting. /// </summary> /// <returns></returns> protected override Task OnDisconnect() { TaskCompletionSource <object> source = new TaskCompletionSource <object>(); ThreadFactory.StartNew(() => { try { if (_serialPort != null) { _serialPort.DataReceived -= OnSerialPortDataReceived; } _serialPort.Close(); _serialPort.Dispose(); _serialPort.DataReceived -= OnSerialPortDataReceived; if (!source.Task.IsCompleted) { source.SetResult(true); } } catch (Exception ex) { if (!source.Task.IsCompleted) { source.SetException(ex); } } }); TimeoutTask.StartNew(() => { if (!source.Task.IsCompleted) { Logger.LogCritical(new IOException($"The serial port seems to be in a froze state. Reinitialize the port and try again.")); source.SetResult(true); } }, TimeSpan.FromSeconds(5)); return(source.Task); }
/// <summary> /// Begins the hand shake. /// This method will block execution until the handshake has completed. /// </summary> /// <exception cref="InvalidOperationException">Must call reset before attempting to begin a handshake.</exception> /// <exception cref="TimeoutException">Could not initiate a handshake within the given timeout.</exception> public void BeginHandShake() { if (!_wasReset) { throw new InvalidOperationException("Must call reset before attempting to begin a handshake."); } if (State == ResonanceHandShakeState.Idle) { Logger.LogDebug("Starting handshake..."); State = ResonanceHandShakeState.InProgress; Logger.LogDebug("Sending Handshake Request..."); ResonanceHandShakeMessage request = new ResonanceHandShakeMessage(); request.Type = ResonanceHandShakeMessageType.Request; request.ClientId = ClientID; request.RequireEncryption = EncryptionEnabled; request.EncryptionPublicKey = _publicKey; OnWriteHandShake(HandShakeTranscoder.Encode(request)); } bool cancel = false; TimeoutTask.StartNew(() => { cancel = true; }, TimeSpan.FromSeconds(10)); while (State != ResonanceHandShakeState.Completed && !cancel) { Thread.Sleep(10); } if (cancel) { throw new TimeoutException("Could not initiate a handshake within the given timeout."); } }
private Task <WebRTCSessionDescription> CreateOffer() { TaskCompletionSource <WebRTCSessionDescription> completion = new TaskCompletionSource <WebRTCSessionDescription>(); ManagedConductor.OnCallbackSdp del = null; bool completed = false; del = (sdp) => { if (!completed) { completed = true; _conductor.OnSuccessOffer -= del; completion.SetResult(new WebRTCSessionDescription() { InternalType = RTCSdpType.offer, Sdp = sdp }); } }; _conductor.OnSuccessOffer += del; TimeoutTask.StartNew(() => { if (!completed) { completed = true; completion.SetException(new TimeoutException("The offer was not created within the given time.")); } }, TimeSpan.FromSeconds(10)); _conductor.CreateOffer(); return(completion.Task); }
/// <summary> /// Called when the adapter is connecting. /// </summary> /// <returns></returns> protected override Task OnConnect() { TaskCompletionSource <object> completion = new TaskCompletionSource <object>(); bool completed = false; Task.Factory.StartNew(() => { if (_socket == null) { if (LocalEndPoint == null) { LocalEndPoint = new IPEndPoint(IPAddress.Any, 0); } if (_isServerClient) { _socket = new UdpClient(LocalEndPoint); _socket.EnableBroadcast = true; TimeoutTask.StartNew(() => { if (!completed) { completed = true; completion.SetException(new TimeoutException("Could not connect within the given timeout.")); } }, ConnectionTimeout); String response = null; try { while (true) { byte[] requestData = Encoding.ASCII.GetBytes(CONNECTION_REQUEST_STRING); _socket.Send(requestData, requestData.Length, RemoteEndPoint); var remoteEndPoint = RemoteEndPoint; byte[] responseData = _socket.Receive(ref remoteEndPoint); response = Encoding.ASCII.GetString(responseData); RemoteEndPoint = remoteEndPoint; if (response == CONNECTION_RESPONSE_STRING_CONFIRMED || response == CONNECTION_RESPONSE_STRING_DECLINED) { break; } } if (response == CONNECTION_RESPONSE_STRING_DECLINED) { throw new Exception("The remote host has declined the connection request."); } } catch (Exception ex) { if (!completed) { completed = true; completion.SetException(ex); } } } else { _socket = new UdpClient(); _socket.EnableBroadcast = true; _socket.ExclusiveAddressUse = false; _socket.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); _socket.Client.Bind(LocalEndPoint); } } if (!completed) { completed = true; State = ResonanceComponentState.Connected; _pullThread = new Thread(PullThreadMethod); _pullThread.IsBackground = true; _pullThread.Name = $"{this} pull thread"; _pullThread.Start(); completion.SetResult(true); } }); return(completion.Task); }
/// <summary> /// Starts the connection. /// </summary> /// <returns></returns> public Task StartAsync() { if (IsStarted) { return(Task.FromResult(true)); } TaskCompletionSource <object> completion = new TaskCompletionSource <object>(); bool completed = false; Task.Factory.StartNew(() => { try { var urlHub = SplitUrl(Url); _connection = new HubConnection(urlHub.url); _proxy = _connection.CreateHubProxy(urlHub.hub); _connection.StateChanged += (x) => { if (x.NewState == ConnectionState.Connected) { if (!completed) { IsStarted = true; completed = true; completion.SetResult(true); } } }; bool reconnecting = false; _connection.Error += (exception) => { if (EnableAutoReconnection) { if (reconnecting && _connection.State == ConnectionState.Reconnecting && exception.GetType() == typeof(TimeoutException)) { Error?.Invoke(this, new ResonanceExceptionEventArgs(exception)); } } }; _connection.Reconnecting += () => { if (!reconnecting) { reconnecting = true; if (EnableAutoReconnection) { Reconnecting?.Invoke(this, new EventArgs()); } else if (_connection.LastError != null) { try { Stop(); Error?.Invoke(this, new ResonanceExceptionEventArgs(_connection.LastError)); } catch { } } } }; _connection.Reconnected += () => { if (EnableAutoReconnection) { reconnecting = false; Reconnected?.Invoke(this, new EventArgs()); } }; _connection.Start(); } catch (Exception ex) { if (!completed) { completed = true; completion.SetException(ex); } } }); TimeoutTask.StartNew(() => { if (!completed) { completed = true; completion.SetException(new TimeoutException("Could not establish the connection within the given timeout.")); } }, TimeSpan.FromSeconds(10)); return(completion.Task); }
protected override Task OnConnect() { _connectionCompleted = false; _closeConnection = false; _receivedSegments = new List <byte[]>(); _expectedSegments = 0; _expectedSegmentsCheckSum = null; _incomingQueue = new ProducerConsumerQueue <byte[]>(); _conductorInitialized = false; _connectionCompletionSource = new TaskCompletionSource <object>(); _signalingTransporter.RegisterRequestHandler <WebRTCIceCandidateRequest, WebRTCIceCandidateResponse>(OnWebRTCCandidateRequest); Logger.LogDebug("Initializing adapter with role '{Role}'.", Role); if (Role == WebRTCAdapterRole.Accept) { ThreadFactory.StartNew(async() => { try { await InitConnection(); if (_offerRequest != null) { Logger.LogDebug("Adapter initialized by an offer request. sending answer..."); var response = await OnWebRTCOfferRequest(_offerRequest); if (_closeConnection) { return; } _signalingTransporter.SendResponse(response.Response, _offerRequestToken); } else { Logger.LogDebug("Waiting for WebRTC offer..."); } } catch (Exception ex) { if (!_connectionCompleted) { _connectionCompleted = true; _connectionCompletionSource.SetException(new ResonanceWebRTCConnectionFailedException(ex)); _closeConnection = true; } } }); } else { ThreadFactory.StartNew(async() => { try { await InitConnection(); var offer = await CreateOffer(); var response = await _signalingTransporter.SendRequestAsync <WebRTCOfferRequest, WebRTCOfferResponse>(new WebRTCOfferRequest() { Offer = offer, }, new ResonanceRequestConfig() { Timeout = TimeSpan.FromSeconds(30) }); _conductor.OnOfferReply("answer", response.Answer.Sdp); FlushIceCandidates(); } catch (Exception ex) { if (!_connectionCompleted) { _connectionCompleted = true; _connectionCompletionSource.SetException(new ResonanceWebRTCConnectionFailedException(ex)); _closeConnection = true; } } }); } TimeoutTask.StartNew(() => { if (!_connectionCompleted) { _connectionCompleted = true; _connectionCompletionSource.SetException(new ResonanceWebRTCConnectionFailedException(new TimeoutException("Could not initialize the connection within the given timeout."))); _closeConnection = true; } }, ConnectionTimeout); return(_connectionCompletionSource.Task); }
/// <summary> /// Called when the adapter is connecting. /// </summary> /// <returns></returns> protected override Task OnConnect() { bool completed = false; TaskCompletionSource <object> completionSource = new TaskCompletionSource <object>(); Task.Factory.StartNew(() => { try { _client = SignalRClientFactory.Default.Create(Mode, Url); _client.StartAsync().GetAwaiter().GetResult(); if (Role == SignalRAdapterRole.Connect) { _client.On(ResonanceHubMethods.Connected, () => { try { if (!completed) { completed = true; completionSource.SetResult(true); } } catch (Exception ex) { if (!completed) { Logger.LogError(ex, "Error occurred after successful connection."); completed = true; completionSource.SetException(ex); } } }); _client.On(ResonanceHubMethods.Declined, () => { try { if (!completed) { completed = true; var ex = new ConnectionDeclinedException(); Logger.LogError(ex, "Error occurred after session created."); completionSource.SetException(ex); } } catch (Exception ex) { if (!completed) { Logger.LogError(ex, "Error occurred after session created."); completed = true; completionSource.SetException(ex); } } }); } _client.On(ResonanceHubMethods.Disconnected, () => { if (State == ResonanceComponentState.Connected) { //OnDisconnect(false); //Don't know what to do here.. We already have the resonance disconnection message. //Maybe just raise an event.. } }); _client.On(ResonanceHubMethods.ServiceDown, () => { OnFailed(new ServiceDownException()); }); Logger.LogInformation("Authenticating with the remote hub {HubUrl}...", _client.Url); _client.InvokeAsync(ResonanceHubMethods.Login, Credentials).GetAwaiter().GetResult(); if (Role == SignalRAdapterRole.Connect) { Logger.LogInformation("Connecting to service {ServiceId}...", ServiceId); SessionId = _client.InvokeAsync <String>(ResonanceHubMethods.Connect, ServiceId).GetAwaiter().GetResult(); } else { Logger.LogInformation("Accepting connection {SessionId}...", SessionId); _client.InvokeAsync(ResonanceHubMethods.AcceptConnection, SessionId).GetAwaiter().GetResult(); if (!completed) { completed = true; completionSource.SetResult(true); } } _client.On <byte[]>(ResonanceHubMethods.DataAvailable, (data) => { OnDataAvailable(data); }); _client.Error += OnError; _client.Reconnecting += OnReconnecting; _client.Reconnected += OnReconnected; } catch (Exception ex) { completed = true; Logger.LogError(ex, "Error occurred while trying to connect."); completionSource.SetException(ex); } }); TimeoutTask.StartNew(() => { if (!completed) { completed = true; completionSource.SetException(new TimeoutException("Could not connect after the given timeout.")); } }, ConnectionTimeout); return(completionSource.Task); }