public Task Disconnect() { return(Task.Run( async() => { using (await _connectionLock.LockAsync(CancellationToken.None)) { if (_state == MTProtoConnectionState.Disconnected) { return; } _state = MTProtoConnectionState.Disconnected; if (_connectionCts != null) { _connectionCts.Cancel(); _connectionCts.Dispose(); _connectionCts = null; } await _clientTransport.DisconnectAsync(); } }, CancellationToken.None)); }
/// <summary> /// Connect. /// </summary> public async Task <MTProtoConnectResult> Connect(CancellationToken cancellationToken) { var result = MTProtoConnectResult.Other; await Task.Run(async() => { using (await _lock.LockAsync(cancellationToken)) { if (_state == MTProtoConnectionState.Connected) { result = MTProtoConnectResult.Success; return; } Debug.Assert(_state == MTProtoConnectionState.Disconnected); try { _state = MTProtoConnectionState.Connecting; Log.Debug("Connecting..."); await _transport.ConnectAsync(cancellationToken).ToObservable().Timeout(DefaultConnectTimeout); _connectionCts = new CancellationTokenSource(); _connectionCancellationToken = _connectionCts.Token; Log.Debug("Connected."); result = MTProtoConnectResult.Success; } catch (TimeoutException) { result = MTProtoConnectResult.Timeout; Log.Debug(string.Format("Failed to connect due to timeout ({0}s).", DefaultConnectTimeout.TotalSeconds)); } catch (Exception e) { result = MTProtoConnectResult.Other; Log.Debug(e, "Failed to connect."); } finally { switch (result) { case MTProtoConnectResult.Success: _state = MTProtoConnectionState.Connected; break; case MTProtoConnectResult.Timeout: case MTProtoConnectResult.Other: _state = MTProtoConnectionState.Disconnected; break; default: throw new ArgumentOutOfRangeException(); } } } }, cancellationToken).ConfigureAwait(false); return(result); }
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 async Task Disconnect() { await Task.Run(async() => { using (await _lock.LockAsync(CancellationToken.None)) { if (_state == MTProtoConnectionState.Disconnected) { return; } _state = MTProtoConnectionState.Disconnected; if (_connectionCts != null) { _connectionCts.Cancel(); _connectionCts.Dispose(); _connectionCts = null; } await _transport.DisconnectAsync(CancellationToken.None); } }, CancellationToken.None).ConfigureAwait(false); }