public MTProtoClientConnection(
            [NotNull] IClientTransportConfig clientTransportConfig,
            [NotNull] IClientTransportFactory clientTransportFactory,
            [NotNull] TLRig tlRig,
            [NotNull] IMessageIdGenerator messageIdGenerator,
            [NotNull] IMessageCodec messageCodec)
        {
            Argument.IsNotNull(() => clientTransportConfig);
            Argument.IsNotNull(() => clientTransportFactory);
            Argument.IsNotNull(() => tlRig);
            Argument.IsNotNull(() => messageIdGenerator);
            Argument.IsNotNull(() => messageCodec);

            _tlRig = tlRig;
            _messageIdGenerator = messageIdGenerator;
            _messageCodec       = messageCodec;

            DefaultRpcTimeout     = Defaults.RpcTimeout;
            DefaultConnectTimeout = Defaults.ConnectTimeout;

            _methods = new MTProtoAsyncMethods(this);

            InitResponseDispatcher(_responseDispatcher);

            // Init transport.
            _clientTransport = clientTransportFactory.CreateTransport(clientTransportConfig);

            // Connector in/out.
            _clientTransport.ObserveOn(DefaultScheduler.Instance).Do(bytes => LogMessageInOut(bytes, "IN")).Subscribe(ProcessIncomingMessageBytes);
        }
        private void Negotiate(IClientTransport transport)
        {
            ManualResetEvent manualResetEvent = new ManualResetEvent(false);

            var signal = transport.Negotiate(this);

            signal.Finished += (sender, e) =>
            {
                VerifyProtocolVersion(e.Result.ProtocolVersion);

                ConnectionId    = e.Result.ConnectionId;
                ConnectionToken = e.Result.ConnectionToken;

                if (Sending != null)
                {
                    var data = Sending();
                    StartTransport(data);
                    manualResetEvent.Set();
                }
                else
                {
                    StartTransport(null);
                    manualResetEvent.Set();
                }
            };
            manualResetEvent.WaitOne();
            m_initialized = true;
        }
示例#3
0
 public JabbRClient(string url, IClientTransport transport)
 {
     _url = url;
     _connection = new HubConnection(url);
     _chat = _connection.CreateProxy("JabbR.Chat");
     _clientTransport = transport ?? new AutoTransport();
 }
示例#4
0
        private void ResolveTransport(IConnection connection, string data, int index)
        {
            // Pick the current transport
            var transport = _transports[index];

            try
            {
                transport.Start(connection, data);
                _transport = transport;
            }
            catch (Exception)
            {
                var next = index + 1;
                if (next < _transports.Length)
                {
                    // Try the next transport
                    ResolveTransport(connection, data, next);
                }
                else
                {
                    // If there's nothing else to try then just fail
                    throw new NotSupportedException("The transports available were not supported on this client.");
                }
            }
        }
示例#5
0
		public CallProxy(IClientTransport transport, IMethodCallSerializer serializer, IMethodBinder binder, string targetName)
		{
			_transport = transport;
			_serializer = serializer;
			_binder = binder;
			_targetName = targetName;
		}
示例#6
0
        /// <summary>
        /// Starts the <see cref="Connection"/>.
        /// </summary>
        /// <param name="transport">The transport to use.</param>
        /// <returns>A task that represents when the connection has started.</returns>
        public Task Start(IClientTransport transport)
        {
            if (transport == null)
            {
                throw new ArgumentNullException("transport");
            }

            lock (_startLock)
            {
                if (!ChangeState(ConnectionState.Disconnected, ConnectionState.Connecting))
                {
                    return(_connectTask ?? TaskAsyncHelper.Empty);
                }

                _disconnectCts         = new CancellationTokenSource();
                _startTcs              = new DispatchingTaskCompletionSource <object>();
                _receiveQueueMonitor   = new TaskQueueMonitor(this, DeadlockErrorTimeout);
                _receiveQueue          = new TaskQueue(_startTcs.Task, _receiveQueueMonitor);
                _lastQueuedReceiveTask = TaskAsyncHelper.Empty;

                _transport = transport;

                _connectTask = Negotiate(transport);
            }

            return(_connectTask);
        }
示例#7
0
        private void ResolveTransport(IConnection connection, string data, int index)
        {
            // Pick the current transport
            var transport = _transports[index];

            try
            {
                transport.Start(connection, data);
                _transport = transport;
            }
            catch (Exception)
            {
                var next = index + 1;
                if (next < _transports.Length)
                {
                    // Try the next transport
                    ResolveTransport(connection, data, next);
                }
                else
                {
                    // If there's nothing else to try then just fail
                    throw new NotSupportedException("The transports available were not supported on this client.");
                }
            }
        }
示例#8
0
 public JabbRClient(string url, IClientTransport transport)
 {
     _url             = url;
     _connection      = new HubConnection(url);
     _chat            = _connection.CreateProxy("JabbR.Chat");
     _clientTransport = transport ?? new AutoTransport();
 }
示例#9
0
        /// <summary><see cref="Ch.Elca.Iiop.IClientTransportFactory.CreateTransport(IIorProfile)"/></summary>
        public IClientTransport CreateTransport(IIorProfile profile)
        {
            if (profile.ProfileId != TAG_INTERNET_IOP.ConstVal)
            {
                throw new INTERNAL(734, CompletionStatus.Completed_No);
            }
            object sslComponentDataObject = GetSSLComponent(profile, m_codec);

            if (sslComponentDataObject == null)
            {
                throw new INTERNAL(734, CompletionStatus.Completed_No);
            }
            SSLComponentData     sslComponent  = (SSLComponentData)sslComponentDataObject;
            IInternetIiopProfile targetProfile = (IInternetIiopProfile)profile;
            int              port    = sslComponent.GetPort();
            SecurityOptions  options = CreateClientSecurityOptions(sslComponent);
            IPAddress        asIpAddress;
            IClientTransport result =
                IPAddress.TryParse(targetProfile.HostName, out asIpAddress)
                    ? new SslClientTransport(asIpAddress, port, options)
                    : new SslClientTransport(targetProfile.HostName, port, options);

            result.ReceiveTimeOut = m_receiveTimeOut;
            result.SendTimeOut    = m_sendTimeOut;
            return(result);
        }
示例#10
0
        protected ClientContextBase(ISerializer serializer, IClientTransport transport)
        {
            Serializer = serializer;
            Transport  = transport;

            OperationSystem = new OperationSystem(new OperationMap(), new SerializationService(serializer), Transport, HandlerFactory);
        }
示例#11
0
        protected ClientContextBase(ISerializer serializer, IClientTransport transport)
        {
            Serializer = serializer;
            Transport = transport;

            OperationSystem = new OperationSystem(new OperationMap(), new SerializationService(serializer), Transport, HandlerFactory);
        }
示例#12
0
文件: Client.cs 项目: danryd/NetRPC
 public ActualProxy(IClientTransport transport, ISerializer serializer)
     : base(typeof(T))
 {
     this.serializer         = serializer;
     this.transport          = transport;
     this.requestHeaderData  = new Dictionary <string, string>();
     this.responseHeaderData = new Dictionary <string, string>();
 }
示例#13
0
        /// <summary>
        /// Allocate a connection for the message to the given target.
        /// </summary>
        private GiopClientConnection AllocateConnectionForTarget(IMessage msg, IIorProfile target,
                                                                 string targetKey,
                                                                 out uint requestNr)
        {
            GiopClientConnection          result        = null;
            GiopClientInitiatedConnection newConnection = null; // contains the new connection, if one is created

            lock (this) {
                while (result == null)
                {
                    result = GetFromAvailable(targetKey);
                    if (result != null)
                    {
                        break;
                    }
                    else
                    {
                        // if no usable connection, create new one (if possible)
                        if (CanInitiateNewConnection(targetKey))
                        {
                            IClientTransport transport =
                                m_transportFactory.CreateTransport(target);
                            newConnection = CreateClientConnection(targetKey, transport, m_requestTimeOut);
                            result        = newConnection;
                        }
                        else
                        {
                            // wait for connections to become available
                            Monitor.Wait(this); // wait for a new connection to become available.
                        }
                    }
                }
                result.IncrementNumberOfRequests();
                requestNr = result.Desc.ReqNumberGen.GenerateRequestId();
                m_allocatedConnections[msg] = result;
                if (newConnection != null)
                {
                    // Register the new connection, if everything went ok
                    RegisterConnection(targetKey, result);
                }
            }
            if (newConnection != null)
            {
                // open the connection now outside the locked session,
                // to allow other threads to access connection manager during
                // this lenghty operation.
                try {
                    newConnection.OpenConnection();
                } catch (Exception) {
                    lock (this) {
                        // clean up dead connection
                        UnregisterConnection(targetKey, newConnection);
                    }
                    throw;
                }
            }
            return(result);
        }
示例#14
0
 public TInterface CreateProxy <TInterface>(IClientTransport transport, ITargetNameExtractor nameExtractor = null)
 {
     if (nameExtractor == null)
     {
         nameExtractor = new DefaultTargetNameExtractor();
     }
     return(ProxyGen.CreateInstance <TInterface>(new CallProxy(transport, _serializer,
                                                               _binder, nameExtractor.GetTargetName(typeof(TInterface)))));
 }
        /// <summary>
        /// Creates a new instance of <see cref="SignalRTextConnection{TMessage}"/>.
        /// </summary>
        /// <param name="uri">The uri of the server to connect to.</param>
        /// <param name="binding">The binding to use.</param>
        /// <param name="transport">The <see cref="IClientTransport"/> to use.</param>
        public SignalRTextConnection(string uri, IWampTextBinding <TMessage> binding, IClientTransport transport)
        {
            mBinding    = binding;
            mTransport  = transport;
            mConnection = new Connection(uri);

            mConnection.Closed   += OnClosed;
            mConnection.Error    += OnError;
            mConnection.Received += OnReceived;
        }
示例#16
0
        public void CanSendMessage()
        {
            IClientTransport trsp = Substitute.For <IClientTransport>();

            trsp.Request(Arg.Any <string>()).Returns(MessageHelper.GenerateJsonResponse("Method", 4));
            var proxy  = new Client <ProxyThis>(trsp);
            var result = proxy.Proxy().Method("asd");

            result.ShouldEqual(4);
        }
 protected async Task Init(IClientTransport transportWay = null)
 {
     if (transportWay != null)
     {
         await HubConnection.Start(new LongPollingTransport());
     }
     else
     {
         await HubConnection.Start();
     }
 }
示例#18
0
        private void RegisterTCPCommands(IClientTransport transport)
        {
            var cmds = new List <IClientCommand> {
                new JoinRequest(), new LeaveRequest()
            };

            foreach (var cmd in cmds)
            {
                transport.RegisterCommand(cmd.GetType().Name, cmd);
            }
        }
示例#19
0
        private void CheckKeepAlive(TimeSpan timeElapsed)
        {
            // Flags used to detect what kind of follow-up action should be taken.
            var connectionSlow         = false;
            IClientTransport transport = null;

            lock (_connectionStateLock)
            {
                if (_connection.State == ConnectionState.Connected)
                {
                    if (timeElapsed >= _connection.KeepAliveData.Timeout)
                    {
                        if (!TimedOut)
                        {
                            // Connection has been lost
                            _connection.Trace(TraceLevels.Events, "Connection Timed-out : Transport Lost Connection");
                            TimedOut = true;

                            // Capture the transport to call LostConnection on it after the lock ends.
                            // We capture it locally because _connection.Transport may be re-initialized before we call LostConnection
                            // and we don't want to call LostConnection on the re-initialized transport.
                            transport = _connection.Transport;
                        }
                    }
                    else if (timeElapsed >= _connection.KeepAliveData.TimeoutWarning)
                    {
                        if (!HasBeenWarned)
                        {
                            // Inform user and set HasBeenWarned to true
                            _connection.Trace(TraceLevels.Events, "Connection Timeout Warning : Notifying user");
                            HasBeenWarned = true;

                            // We don't want to run the user event "ConnectionSlow" in the lock.
                            connectionSlow = true;
                        }
                    }
                    else
                    {
                        ClearFlags();
                    }
                }
            }

            // If there's a non-null 'transport' value, then it means the connection timed out and we need to call LostConnection.
            if (transport != null)
            {
                transport.LostConnection(_connection);
            }

            if (connectionSlow)
            {
                _connection.OnConnectionSlow();
            }
        }
示例#20
0
        /// <summary>
        /// Starts the <see cref="Connection"/>.
        /// </summary>
        /// <param name="transport">The transport to use.</param>
        /// <returns>A task that represents when the connection has started.</returns>
        public virtual Task Start(IClientTransport transport)
        {
            if (!ChangeState(ConnectionState.Disconnected, ConnectionState.Connecting))
            {
                return(TaskAsyncHelper.Empty);
            }

            _transport = transport;

            return(Negotiate(transport));
        }
示例#21
0
        public virtual void Start(IClientTransport transport)
        {
            if (IsActive)
            {
                return;
            }

            IsActive    = true;
            m_transport = transport;
            Negotiate(transport);
        }
 public OperationState RegisterReceiveCommand <T>(IClientTransport transport, T execute) where T : IClientCommand
 {
     if (transport == null)
     {
         throw new ArgumentNullException(nameof(transport));
     }
     if (execute == null)
     {
         throw new ArgumentNullException(nameof(execute));
     }
     return(RegisterReceiveCommand(transport, typeof(T).Name, execute));
 }
示例#23
0
 public ConsumerMetric(string connectionId, IClientTransport transport, IEnumerable <long> ticks, long frequency, string format)
 {
     _connectionId = connectionId;
     _transport    = transport;
     _frequency    = frequency;
     _ticks        = ticks.ToList();
     _format       = format;
     Max           = _ticks.Max();
     Min           = _ticks.Min();
     Count         = _ticks.Count();
     Average       = _ticks.Sum() / _ticks.Count;
 }
示例#24
0
        /// <param name="connectionKey">the key describing the connection</param>
        /// <param name="transport">a not yet connected client transport</param>
        /// <param name="headerFlags">the header flags to use for transport related giop messages.</param>
        internal GiopClientInitiatedConnection(string connectionKey, IClientTransport transport,
                                               MessageTimeout requestTimeOut, GiopClientConnectionManager conManager,
                                               bool supportBidir, byte headerFlags)
        {
            GiopRequestNumberGenerator reqNumberGen =
                (!supportBidir ? new GiopRequestNumberGenerator() : new GiopRequestNumberGenerator(true));
            GiopTransportMessageHandler handler =
                new GiopTransportMessageHandler(transport, requestTimeOut, headerFlags);
            GiopClientConnectionDesc conDesc = new GiopClientConnectionDesc(conManager, this, reqNumberGen, handler);

            m_clientTransport = transport;
            Initalize(connectionKey, handler, conDesc);
        }
示例#25
0
        private void Disconnect()
        {
            lock (_stateLock)
            {
                // Do nothing if the connection is offline
                if (State != ConnectionState.Disconnected)
                {
                    // Change state before doing anything else in case something later in the method throws
                    State = ConnectionState.Disconnected;

                    Trace(TraceLevels.StateChanges, "Disconnected");

                    _disconnectTimeoutOperation.Dispose();
                    _disconnectCts.Cancel();
                    _disconnectCts.Dispose();

                    _receiveQueueMonitor.Dispose();

                    if (Monitor != null)
                    {
                        Monitor.Dispose();
                    }

                    if (_transport != null)
                    {
                        Trace(TraceLevels.Events, "Transport.Dispose({0})", ConnectionId);

                        _transport.Dispose();
                        _transport = null;
                    }

                    Trace(TraceLevels.Events, "Closed");

                    // Clear the state for this connection
                    ConnectionId       = null;
                    ConnectionToken    = null;
                    GroupsToken        = null;
                    MessageId          = null;
                    _connectionData    = null;
                    _actualUrl         = _userUrl;
                    _actualQueryString = _userQueryString;

                    // Clear the buffer
                    // PORT: In 2.3.0 this was only present in the UWP and PCL versions.
                    _traceWriter.Flush();

                    // TODO: Do we want to trigger Closed if we are connecting?
                    OnClosed();
                }
            }
        }
示例#26
0
        public JsonRpcModule(IClientTransport clientTransport)
        {
            this.RequiresAuthentication();

            Post["/jsonrpc"] = _ =>
            {
                using (var ms = new MemoryStream())
                {
                    Request.Body.CopyTo(ms);
                    var json = Encoding.UTF8.GetString(ms.ToArray());
                    return clientTransport.Call(json);
                }
            };
        }
示例#27
0
        public MTProtoClientConnection(
            [NotNull] IClientTransportConfig clientTransportConfig,
            [NotNull] IClientTransportFactory clientTransportFactory,
            [NotNull] TLRig tlRig,
            [NotNull] IMessageIdGenerator messageIdGenerator,
            [NotNull] IMessageCodec messageCodec)
        {
            _tlRig = tlRig;
            _messageIdGenerator = messageIdGenerator;
            _messageCodec       = messageCodec;

            DefaultRpcTimeout     = Defaults.RpcTimeout;
            DefaultConnectTimeout = Defaults.ConnectTimeout;

            _methods = new MTProtoAsyncMethods(this);

            _updatesHandler = new UpdatesHandler(_tlRig);

            InitResponseDispatcher(_responseDispatcher);

            // Init transport.
            _clientTransport = clientTransportFactory.CreateTransport(clientTransportConfig);

            // Connector in/out.
            _clientTransport.ObserveOn(DefaultScheduler.Instance).Do(bytes => LogMessageInOut(bytes, "IN")).Subscribe(ProcessIncomingMessageBytes);

            _clientTransport.RegisterOnDisconnectInternally(() =>
            {
                Console.WriteLine("Client has been closed internally.");

                if (_onClosedInternally != null)
                {
                    _onClosedInternally(this, null);
                }

                if (_state == MTProtoConnectionState.Disconnected)

                {
                    return;
                }
                _state = MTProtoConnectionState.Disconnected;

                if (_connectionCts != null)
                {
                    _connectionCts.Cancel();
                    _connectionCts.Dispose();
                    _connectionCts = null;
                }
            });
        }
示例#28
0
        public JsonRpcModule(IClientTransport clientTransport)
        {
            this.RequiresAuthentication();

            Post["/jsonrpc"] = _ =>
            {
                using (var ms = new MemoryStream())
                {
                    Request.Body.CopyTo(ms);
                    var json = Encoding.UTF8.GetString(ms.ToArray());
                    return(clientTransport.Call(json));
                }
            };
        }
示例#29
0
        private void Disconnect()
        {
            lock (_stateLock)
            {
                // Do nothing if the connection is offline
                if (State != ConnectionState.Disconnected)
                {
                    // Change state before doing anything else in case something later in the method throws
                    State = ConnectionState.Disconnected;

                    Trace(TraceLevels.StateChanges, "Disconnected");

                    _disconnectTimeoutOperation.Dispose();
                    _disconnectCts.Cancel();
                    _disconnectCts.Dispose();

                    _receiveQueueMonitor.Dispose();

                    if (Monitor != null)
                    {
                        Monitor.Dispose();
                    }

                    if (_transport != null)
                    {
                        Trace(TraceLevels.Events, "Transport.Dispose({0})", ConnectionId);

                        _transport.Dispose();
                        _transport = null;
                    }

                    Trace(TraceLevels.Events, "Closed");

                    // Clear the state for this connection
                    ConnectionId    = null;
                    ConnectionToken = null;
                    GroupsToken     = null;
                    MessageId       = null;
                    _connectionData = null;

#if NETFX_CORE || PORTABLE
                    // Clear the buffer
                    _traceWriter.Flush();
#endif
                    // TODO: Do we want to trigger Closed if we are connecting?
                    OnClosed();
                }
            }
        }
示例#30
0
        /// <summary>
        /// Starts the <see cref="Connection"/>.
        /// </summary>
        /// <param name="transport">The transport to use.</param>
        /// <returns>A task that represents when the connection has started.</returns>
        public virtual Task Start(IClientTransport transport)
        {
            if (State == ConnectionState.Connected ||
                State == ConnectionState.Connecting)
            {
                return(TaskAsyncHelper.Empty);
            }

            State   = ConnectionState.Connecting;
            _cancel = new CancellationTokenSource();

            _transport = transport;

            return(Negotiate(transport));
        }
示例#31
0
        public DataWellClient(string Host, string Port, TransportTypes transportType)
        {
            switch (transportType)
            {
            case TransportTypes.WebSocket:
                _transport = new WSClientTransport(Host, Port);
                break;

            case TransportTypes.Http:
                throw new NotImplementedException();
                break;

            default: throw new Exception("This type of transport is not supported");
            }
        }
示例#32
0
        private Task Negotiate(IClientTransport transport)
        {
            var negotiateTcs = new TaskCompletionSource <object>();

            transport.Negotiate(this).Then(negotiationResponse =>
            {
                VerifyProtocolVersion(negotiationResponse.ProtocolVersion);

                ConnectionId       = negotiationResponse.ConnectionId;
                _disconnectTimeout = TimeSpan.FromSeconds(negotiationResponse.DisconnectTimeout);

                var data = OnSending();
                StartTransport(data).ContinueWith(negotiateTcs);
            })
            .ContinueWithNotComplete(negotiateTcs);

            var tcs = new TaskCompletionSource <object>();

            negotiateTcs.Task.ContinueWith(task =>
            {
                try
                {
                    // If there's any errors starting then Stop the connection
                    if (task.IsFaulted)
                    {
                        Disconnect();
                        tcs.SetException(task.Exception.Unwrap());
                    }
                    else if (task.IsCanceled)
                    {
                        Disconnect();
                        tcs.SetCanceled();
                    }
                    else
                    {
                        tcs.SetResult(null);
                    }
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }
            },
                                           TaskContinuationOptions.ExecuteSynchronously);

            return(tcs.Task);
        }
示例#33
0
        public void Stop(TimeSpan timeout)
        {
            lock (_startLock)
            {
                // Wait for the connection to connect
                if (_connectTask != null)
                {
                    try
                    {
                        _connectTask.Wait(timeout);
                    }
                    catch (Exception ex)
                    {
                        Trace(TraceLevels.Events, "Error: {0}", ex.GetBaseException());
                    }
                }

                lock (_stateLock)
                {
                    // Do nothing if the connection is offline
                    if (State != ConnectionState.Disconnected)
                    {
                        string connectionId = ConnectionId;

                        Trace(TraceLevels.Events, "Stop");

                        // Dispose the heart beat monitor so we don't fire notifications when waiting to abort
                        _monitor.Dispose();

                        _transport.Abort(this, timeout);

                        Disconnect();

                        _disconnectCts.Dispose();

                        if (_transport != null)
                        {
                            Trace(TraceLevels.Events, "Transport.Dispose({0})", connectionId);

                            _transport.Dispose();
                            _transport = null;
                        }
                    }
                }
            }
        }
示例#34
0
        private Task Negotiate(IClientTransport transport)
        {
            var negotiateTcs = new TaskCompletionSource <object>();

            transport.Negotiate(this).Then(negotiationResponse =>
            {
                VerifyProtocolVersion(negotiationResponse.ProtocolVersion);

                ConnectionId = negotiationResponse.ConnectionId;

                if (Sending != null)
                {
                    var data = Sending();
                    StartTransport(data).ContinueWith(negotiateTcs);
                }
                else
                {
                    StartTransport(null).ContinueWith(negotiateTcs);
                }
            })
            .ContinueWithNotComplete(negotiateTcs);

            var tcs = new TaskCompletionSource <object>();

            negotiateTcs.Task.ContinueWith(task =>
            {
                // If there's any errors starting then Stop the connection
                if (task.IsFaulted)
                {
                    Stop();
                    tcs.SetException(task.Exception);
                }
                else if (task.IsCanceled)
                {
                    Stop();
                    tcs.SetCanceled();
                }
                else
                {
                    tcs.SetResult(null);
                }
            },
                                           TaskContinuationOptions.ExecuteSynchronously);

            return(tcs.Task);
        }
示例#35
0
        private void ResolveTransport(IConnection connection, string data, CancellationToken disconnectToken, DispatchingTaskCompletionSource <object> tcs, int index)
        {
            // Pick the current transport
            IClientTransport transport = _transports[index];

            transport.Start(connection, data, disconnectToken).ContinueWith(task =>
            {
                if (task.IsFaulted || task.IsCanceled)
                {
                    Exception ex;
                    if (task.IsCanceled)
                    {
                        ex = new OperationCanceledException(Resources.Error_TaskCancelledException);
                    }
                    else
                    {
                        ex = task.Exception.GetBaseException();
                    }

                    connection.Trace(TraceLevels.Events, "Auto: Failed to connect to using transport {0}. {1}", transport.Name, ex);

                    // If that transport fails to initialize, then fallback.
                    // If it is that /start request that failed, do not fallback.
                    var next = index + 1;
                    if (next < _transports.Count && !(ex is StartException))
                    {
                        // Try the next transport
                        ResolveTransport(connection, data, disconnectToken, tcs, next);
                    }
                    else
                    {
                        // If there's nothing else to try then just fail
                        tcs.SetException(ex);
                    }
                }
                else
                {
                    // Set the active transport
                    _transport = transport;

                    // Complete the process
                    tcs.SetResult(null);
                }
            },
                                                                            TaskContinuationOptions.ExecuteSynchronously);
        }
        public OperationState RegisterReceiveCommand <T>(IClientTransport transport, string commandName, T execute) where T : IClientCommand
        {
            if (transport == null)
            {
                throw new ArgumentNullException(nameof(transport));
            }
            if (string.IsNullOrEmpty(commandName))
            {
                throw new ArgumentNullException(nameof(commandName));
            }
            if (execute == null)
            {
                throw new ArgumentNullException(nameof(execute));
            }

            return(transport.RegisterCommand(commandName, execute));
        }
示例#37
0
 protected void SetReconnectDelay(IClientTransport transport, TimeSpan delay)
 {
     // SUPER ugly, alternative is adding an overload to the create host function, adding a member to the
     // IClientTransport object or using Reflection.  Adding a member to IClientTransport isn't horrible
     // but we want to avoid making a breaking change... Therefore this is the least of the evils.
     if (transport is ServerSentEventsTransport)
     {
         (transport as ServerSentEventsTransport).ReconnectDelay = delay;
     }
     else if (transport is LongPollingTransport)
     {
         (transport as LongPollingTransport).ReconnectDelay = delay;
     }
     else if (transport is WebSocketTransport)
     {
         (transport as WebSocketTransport).ReconnectDelay = delay;
     }
 }
 /// <summary>
 /// see <see cref="Ch.Elca.Iiop.GiopClientConnectionManager.CreateClientConnection"></see>
 /// </summary>
 /// <remarks>for use case (2)</remarks>
 protected override GiopClientInitiatedConnection CreateClientConnection(string targetKey, IClientTransport transport,
                                                                         MessageTimeout requestTimeOut) {
     return new GiopClientInitiatedConnection(targetKey, transport, requestTimeOut, this, true,
                                              m_headerFlags);
 }
示例#39
0
        /// <summary>
        /// Starts the <see cref="Connection"/>.
        /// </summary>
        /// <param name="transport">The transport to use.</param>
        /// <returns>A task that represents when the connection has started.</returns>
        public Task Start(IClientTransport transport)
        {
            _disconnectCts = new SafeCancellationTokenSource();
            if (!ChangeState(ConnectionState.Disconnected, ConnectionState.Connecting))
            {
                return TaskAsyncHelper.Empty;
            }

            _transport = transport;

            return Negotiate(transport);
        }
示例#40
0
        private Task Negotiate(IClientTransport transport)
        {
            _connectionData = OnSending();

            return transport.Negotiate(this, _connectionData)
                            .Then(negotiationResponse =>
                            {
                                VerifyProtocolVersion(negotiationResponse.ProtocolVersion);

                                ConnectionId = negotiationResponse.ConnectionId;
                                ConnectionToken = negotiationResponse.ConnectionToken;
                                _disconnectTimeout = TimeSpan.FromSeconds(negotiationResponse.DisconnectTimeout);
                                _totalTransportConnectTimeout = TransportConnectTimeout + TimeSpan.FromSeconds(negotiationResponse.TransportConnectTimeout);

                                // Default the beat interval to be 5 seconds in case keep alive is disabled.
                                var beatInterval = TimeSpan.FromSeconds(5);

                                // If we have a keep alive
                                if (negotiationResponse.KeepAliveTimeout != null)
                                {
                                    _keepAliveData = new KeepAliveData(TimeSpan.FromSeconds(negotiationResponse.KeepAliveTimeout.Value));
                                    _reconnectWindow = _disconnectTimeout + _keepAliveData.Timeout;

                                    beatInterval = _keepAliveData.CheckInterval;
                                }
                                else
                                {
                                    _reconnectWindow = _disconnectTimeout;
                                }

                                _monitor = new HeartbeatMonitor(this, _stateLock, beatInterval);

                                return StartTransport();
                            })
                            .ContinueWithNotComplete(() => Disconnect());
        }
示例#41
0
        /// <summary>
        /// Starts the <see cref="Connection"/>.
        /// </summary>
        /// <param name="transport">The transport to use.</param>
        /// <returns>A task that represents when the connection has started.</returns>
        public Task Start(IClientTransport transport)
        {
            lock (_startLock)
            {
                if (!ChangeState(ConnectionState.Disconnected, ConnectionState.Connecting))
                {
                    return _connectTask ?? TaskAsyncHelper.Empty;
                }

                _disconnectCts = new CancellationTokenSource();
                _startTcs = new TaskCompletionSource<object>();
                _receiveQueue = new TaskQueue(_startTcs.Task);
                _lastQueuedReceiveTask = TaskAsyncHelper.Empty;

                _transport = transport;

                _connectTask = Negotiate(transport);
            }

            return _connectTask;
        }
示例#42
0
        /// <summary>
        ///     Starts the <see cref="Connection" />.
        /// </summary>
        /// <param name="transport">The transport to use.</param>
        /// <returns>A task that represents when the connection has started.</returns>
        public Task Start(IClientTransport transport)
        {
            lock (_startLock)
            {
                if (!ChangeState(ConnectionState.Disconnected, ConnectionState.Connecting))
                {
                    return _connectTask ?? TaskAsyncHelper.Empty;
                }

                IsActive = true;
                _transport = transport;

                _connectTask = Negotiate(transport);
            }

            return _connectTask;
        }
示例#43
0
 public static IStatrClient Build(IClientTransport clientTransport)
 {
     return new StatrClient(clientTransport);
 }
        private Task Negotiate(IClientTransport transport)
        {
            _connectionData = OnSending();

            return transport.Negotiate(this, _connectionData)
                            .Then(negotiationResponse =>
                            {
                                VerifyProtocolVersion(negotiationResponse.ProtocolVersion);

                                ConnectionId = negotiationResponse.ConnectionId;
                                ConnectionToken = negotiationResponse.ConnectionToken;
                                _disconnectTimeout = TimeSpan.FromSeconds(negotiationResponse.DisconnectTimeout);
                                TransportConnectTimeout = TransportConnectTimeout + TimeSpan.FromSeconds(negotiationResponse.TransportConnectTimeout);

                                // If we have a keep alive
                                if (negotiationResponse.KeepAliveTimeout != null)
                                {
                                    _keepAliveData = new KeepAliveData(TimeSpan.FromSeconds(negotiationResponse.KeepAliveTimeout.Value));
                                }

                                return StartTransport();
                            })
                            .ContinueWithNotComplete(() => Disconnect());
        }
示例#45
0
            public void FallbackToLongPollingIIS()
            {
                using (ITestHost host = new IISExpressTestHost())
                {
                    host.Initialize();

                    var connection = CreateConnection(host.Url + "/fall-back");
                    var tcs = new TaskCompletionSource<object>();

                    connection.StateChanged += change =>
                    {
                        if (change.NewState == ConnectionState.Reconnecting)
                        {
                            tcs.TrySetException(new Exception("The connection should not be reconnecting"));
                        }
                    };

                    var client = new DefaultHttpClient();
                    var transports = new IClientTransport[]  {
                        new ServerSentEventsTransport(client) { ConnectionTimeout = TimeSpan.Zero },
                        new LongPollingTransport(client)
                    };

                    var transport = new AutoTransport(client, transports);

                    connection.Start(transport).Wait();

                    Assert.Equal(connection.Transport.Name, "longPolling");

                    Assert.False(tcs.Task.Wait(TimeSpan.FromSeconds(5)));

                    connection.Stop();
                }
            }
示例#46
0
        private Task Negotiate(IClientTransport transport)
        {
            var negotiateTcs = new TaskCompletionSource<object>();

            transport.Negotiate(this).Then(negotiationResponse =>
            {
                VerifyProtocolVersion(negotiationResponse.ProtocolVersion);

                ConnectionId = negotiationResponse.ConnectionId;
                ConnectionToken = negotiationResponse.ConnectionToken;

                _disconnectTimeout = TimeSpan.FromSeconds(negotiationResponse.DisconnectTimeout);

                var data = OnSending();
                StartTransport(data).ContinueWith(negotiateTcs);
            })
            .ContinueWithNotComplete(negotiateTcs);

            var tcs = new TaskCompletionSource<object>();
            negotiateTcs.Task.ContinueWith(task =>
            {
                try
                {
                    // If there's any errors starting then Stop the connection
                    if (task.IsFaulted)
                    {
                        Disconnect();
                        tcs.SetException(task.Exception.Unwrap());
                    }
                    else if (task.IsCanceled)
                    {
                        Disconnect();
                        tcs.SetCanceled();
                    }
                    else
                    {
                        tcs.SetResult(null);
                    }
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }
            },
            TaskContinuationOptions.ExecuteSynchronously);

            return tcs.Task;
        }
示例#47
0
		public override void Start(IClientTransport transport)
		{
			Sending += OnConnectionSending;

			base.Start(transport);
		}
示例#48
0
        private void ResolveTransport(IConnection connection, string data, CancellationToken disconnectToken, TaskCompletionSource<object> tcs, int index)
        {
            // Pick the current transport
            IClientTransport transport = _transports[index];

            transport.Start(connection, data, disconnectToken).ContinueWith(task =>
            {
                if (task.IsFaulted)
                {
            #if !WINDOWS_PHONE && !SILVERLIGHT && !NETFX_CORE
                    // Make sure we observe the exception
                    var ex = task.Exception;
                    Trace.TraceError("SignalR exception thrown by Task: {0}", ex);
            #endif
            #if NET35
                    Debug.WriteLine(System.String.Format(CultureInfo.InvariantCulture, "Auto: Failed to connect to using transport {0}", (object)transport.GetType().Name));
            #else
                    Debug.WriteLine("Auto: Failed to connect to using transport {0}", (object)transport.GetType().Name);
            #endif

                    // If that transport fails to initialize then fallback
                    var next = index + 1;
                    if (next < _transports.Count)
                    {
                        // Try the next transport
                        ResolveTransport(connection, data, disconnectToken, tcs, next);
                    }
                    else
                    {
                        // If there's nothing else to try then just fail
                        tcs.SetException(task.Exception);
                    }
                }
                else
                {
                    // Set the active transport
                    _transport = transport;

                    // Complete the process
                    tcs.SetResult(null);
                }

            },
            TaskContinuationOptions.ExecuteSynchronously);
        }
示例#49
0
        private Task Negotiate(IClientTransport transport)
        {
            return transport.Negotiate(this)
                .ContinueWithNewResult(task =>
                {
                    var response = task.Result;

                    VerifyProtocolVersion(response.ProtocolVersion);

                    ConnectionId = response.ConnectionId;
                    ConnectionToken = response.ConnectionToken;

                    var data = OnSending();
                    StartTransport(data);

                    return response;
                });
        }
示例#50
0
        private void ResolveTransport(IConnection connection, string data, CancellationToken disconnectToken, TaskCompletionSource<object> tcs, int index)
        {
            // Pick the current transport
            IClientTransport transport = _transports[index];

            transport.Start(connection, data, disconnectToken).ContinueWith(task =>
            {
                if (task.IsFaulted || task.IsCanceled)
                {
                    Exception ex;
                    if (task.IsCanceled)
                    {
                        ex = new OperationCanceledException(Resources.Error_TaskCancelledException);
                    }
                    else
                    {
                        ex = task.Exception.GetBaseException();
                    }

                    connection.Trace(TraceLevels.Events, "Auto: Failed to connect to using transport {0}. {1}", transport.Name, ex);

                    // If that transport fails to initialize, then fallback.
                    // If it is that /start request that failed, do not fallback.
                    var next = index + 1;
                    if (next < _transports.Count && !(ex is StartException))
                    {
                        // Try the next transport
                        ResolveTransport(connection, data, disconnectToken, tcs, next);
                    }
                    else
                    {
                        // If there's nothing else to try then just fail
                        tcs.SetException(ex);
                    }
                }
                else
                {
                    // Set the active transport
                    _transport = transport;

                    // Complete the process
                    tcs.SetResult(null);
                }

            },
            TaskContinuationOptions.ExecuteSynchronously);
        }
 private static IClientTransportFactory CreateMockTransportFactory(IClientTransport clientTransport)
 {
     var mockTransportFactory = new Mock<IClientTransportFactory>();
     mockTransportFactory.Setup(manager => manager.CreateTransport(It.IsAny<IClientTransportConfig>())).Returns(() => clientTransport);
     return mockTransportFactory.Object;
 }
        private void ResolveTransport(IConnection connection, string data, CancellationToken disconnectToken, TaskCompletionSource<object> tcs, int index)
        {
            // Pick the current transport
            IClientTransport transport = _transports[index];

            transport.Start(connection, data, disconnectToken).ContinueWith(task =>
            {
                if (task.IsFaulted)
                {
                    // Make sure we observe the exception
                    var ex = task.Exception.GetBaseException();

                    connection.Trace(TraceLevels.Events, "Auto: Failed to connect to using transport {0}. {1}", transport.Name, ex);

                    // If that transport fails to initialize then fallback
                    var next = index + 1;
                    if (next < _transports.Count)
                    {
                        // Try the next transport
                        ResolveTransport(connection, data, disconnectToken, tcs, next);
                    }
                    else
                    {
                        // If there's nothing else to try then just fail
                        tcs.SetException(task.Exception);
                    }
                }
                else
                {
                    // Set the active transport
                    _transport = transport;

                    // Complete the process
                    tcs.SetResult(null);
                }

            },
            TaskContinuationOptions.ExecuteSynchronously);
        }
        /// <summary>
        /// Starts the <see cref="Connection"/>.
        /// </summary>
        /// <param name="transport">The transport to use.</param>
        /// <returns>A task that represents when the connection has started.</returns>
        public Task Start(IClientTransport transport)
        {
            lock (_startLock)
            {
                _connectTask = TaskAsyncHelper.Empty;
                _disconnectCts = new CancellationTokenSource();

                if (!ChangeState(ConnectionState.Disconnected, ConnectionState.Connecting))
                {
                    return _connectTask;
                }

                _monitor = new HeartbeatMonitor(this, _stateLock);
                _transport = transport;

                _connectTask = Negotiate(transport);
            }

            return _connectTask;
        }
示例#54
0
 private StatrClient(IClientTransport clientTransport)
 {
     Transport = clientTransport;
 }
        private void Disconnect()
        {
            lock (_stateLock)
            {
                // Do nothing if the connection is offline
                if (State != ConnectionState.Disconnected)
                {
                    // Change state before doing anything else in case something later in the method throws
                    State = ConnectionState.Disconnected;

                    Trace(TraceLevels.StateChanges, "Disconnected");

                    // If we've connected then instantly disconnected we may have data in the incomingMessageBuffer
                    // Therefore we need to clear it incase we start the connection again.
                    _connectingMessageBuffer.Clear();

                    _disconnectTimeoutOperation.Dispose();
                    _disconnectCts.Cancel();
                    _disconnectCts.Dispose();
                    _monitor.Dispose();

                    if (_transport != null)
                    {
                        Trace(TraceLevels.Events, "Transport.Dispose({0})", ConnectionId);

                        _transport.Dispose();
                        _transport = null;
                    }

                    Trace(TraceLevels.Events, "Closed");

                    // Clear the state for this connection
                    ConnectionId = null;
                    ConnectionToken = null;
                    GroupsToken = null;
                    MessageId = null;
                    _connectionData = null;

#if NETFX_CORE || PORTABLE
                    // Clear the buffer
                    _traceWriter.Flush();
#endif
                    // TODO: Do we want to trigger Closed if we are connecting?
                    OnClosed();
                }
            }
        }
示例#56
0
            public async Task FallbackToLongPollingIIS()
            {
                using (ITestHost host = CreateHost(HostType.IISExpress))
                {
                    // Reduce transportConnectionTimeout to 5 seconds
                    host.Initialize(transportConnectTimeout: 5);

                    var connection = CreateConnection(host, "/fall-back");

                    using (connection)
                    {
                        var tcs = new TaskCompletionSource<object>();

                        connection.StateChanged += change =>
                        {
                            if (change.NewState == ConnectionState.Reconnecting)
                            {
                                tcs.TrySetException(new Exception("The connection should not be reconnecting"));
                            }
                        };

                        var client = new DefaultHttpClient();
                        var transports = new IClientTransport[]  {
                            new ServerSentEventsTransport(client),
                            new LongPollingTransport(client)
                        };

                        var transport = new AutoTransport(client, transports);

                        await connection.Start(transport);

                        Assert.Equal(connection.Transport.Name, "longPolling");

                        Assert.False(tcs.Task.Wait(TimeSpan.FromSeconds(5)));
                    }
                }
            }
示例#57
0
        public void Stop(TimeSpan timeout)
        {
            lock (_startLock)
            {
                // Wait for the connection to connect
                if (_connectTask != null)
                {
                    try
                    {
                        _connectTask.Wait(timeout);
                    }
                    catch (Exception ex)
                    {
                        Trace(TraceLevels.Events, "Error: {0}", ex.GetBaseException());
                    }
                }

                lock (_stateLock)
                {
                    // Do nothing if the connection is offline
                    if (State != ConnectionState.Disconnected)
                    {
                        string connectionId = ConnectionId;

                        Trace(TraceLevels.Events, "Stop");

                        // Dispose the heart beat monitor so we don't fire notifications when waiting to abort
                        _monitor.Dispose();

                        _transport.Abort(this, timeout);

                        Disconnect();

                        _disconnectCts.Dispose();

                        if (_transport != null)
                        {
                            Trace(TraceLevels.Events, "Transport.Dispose({0})", connectionId);

                            _transport.Dispose();
                            _transport = null;
                        }
                    }
                }
            }
        }
 public ConsoleClientContext(ISerializer serializer, IClientTransport transport)
     : base(serializer, transport)
 {
 }
示例#59
0
 public override Task Start(IClientTransport transport)
 {
     Sending += OnConnectionSending;
     Received += OnConnectionReceived;
     return base.Start(transport);
 }
示例#60
0
        /// <summary>
        /// Starts the <see cref="Connection"/>.
        /// </summary>
        /// <param name="transport">The transport to use.</param>
        /// <returns>A task that represents when the connection has started.</returns>
        public Task Start(IClientTransport transport)
        {
            if (transport == null)
            {
                throw new ArgumentNullException("transport");
            }

            lock (_startLock)
            {
                if (!ChangeState(ConnectionState.Disconnected, ConnectionState.Connecting))
                {
                    return _connectTask ?? TaskAsyncHelper.Empty;
                }

                _disconnectCts = new CancellationTokenSource();
                _startTcs = new TaskCompletionSource<object>();
                _receiveQueueMonitor = new TaskQueueMonitor(this, DeadlockErrorTimeout);
                _receiveQueue = new TaskQueue(_startTcs.Task, _receiveQueueMonitor);
                _lastQueuedReceiveTask = TaskAsyncHelper.Empty;

                _transport = transport;

                _connectTask = Negotiate(transport);
            }

            return _connectTask;
        }