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; }
public JabbRClient(string url, IClientTransport transport) { _url = url; _connection = new HubConnection(url); _chat = _connection.CreateProxy("JabbR.Chat"); _clientTransport = transport ?? new AutoTransport(); }
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."); } } }
public CallProxy(IClientTransport transport, IMethodCallSerializer serializer, IMethodBinder binder, string targetName) { _transport = transport; _serializer = serializer; _binder = binder; _targetName = targetName; }
/// <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); }
/// <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); }
protected ClientContextBase(ISerializer serializer, IClientTransport transport) { Serializer = serializer; Transport = transport; OperationSystem = new OperationSystem(new OperationMap(), new SerializationService(serializer), Transport, HandlerFactory); }
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>(); }
/// <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); }
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; }
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(); } }
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); } }
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(); } }
/// <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)); }
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)); }
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; }
/// <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); }
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(); } } }
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); } }; }
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; } }); }
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)); } }; }
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(); } } }
/// <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)); }
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"); } }
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); }
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; } } } } }
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); }
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)); }
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); }
/// <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); }
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()); }
/// <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; }
/// <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; }
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()); }
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(); } }
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; }
public override void Start(IClientTransport transport) { Sending += OnConnectionSending; base.Start(transport); }
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); }
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; }); }
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; }
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(); } } }
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))); } } }
public ConsoleClientContext(ISerializer serializer, IClientTransport transport) : base(serializer, transport) { }
public override Task Start(IClientTransport transport) { Sending += OnConnectionSending; Received += OnConnectionReceived; return base.Start(transport); }
/// <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; }