示例#1
0
        /// <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);
        }
示例#2
0
        /// <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);
        }
示例#3
0
        /// <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.");
            }
        }
示例#4
0
        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);
        }
示例#5
0
        /// <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);
        }
示例#6
0
        /// <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);
        }
示例#7
0
        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);
        }
示例#8
0
        /// <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);
        }