/// <summary> /// Retorna o transporte para a conexão atual. /// Se ainda não estiver conectado, tenta conectar no servidor. /// O estado desconctado é um estado terminal. /// Retorna uma excessão caso não consiga conectar no servidor. /// </summary> /// <param name="forceConnect">Força uma reconexão mesmo que esteja desconectado.</param> /// <returns>O transporte atualmente conectado.</returns> protected IPacketTransport InternalGetTransport(bool forceConnect) { if (m_State == ChannelState.Connected) { return(m_transport); } lock (m_transportInitializeLock) { if (m_State == ChannelState.Connected) { return(m_transport); } if (!forceConnect) { if (m_State != ChannelState.NotConnected) { SocketException sex = new SocketException((int)SocketError.NotConnected); throw sex; } } m_State = ChannelState.Connecting; TcpClient client = new TcpClient(); IPacketTransport transport = null; try { client.Connect(m_remoteHostName, m_remotePort); // TODO: Channel: implement multiple transport options transport = new PacketTransport(client); transport.SetReceiveAction(OnPacketReceived); transport.SetDisconnectAction(OnDisconnected); transport.Start(); m_transport = transport; m_State = ChannelState.Connected; return(m_transport); } catch (Exception) { m_State = ChannelState.NotConnected; client?.Close(); transport?.Dispose(); throw; } } }
/// <summary> /// Finaliza a sessão, encerrando todas as RPCs pendentes e liberando os recursos alocados. /// </summary> private void InternalClose() { m_Transport?.Dispose(); m_Transport = null; var rpcs = m_Rpcs; m_Rpcs = null; if (rpcs != null) { foreach (var rpc in rpcs.Values.ToArray()) { rpc.Cancel(); rpc.Dispose(); } rpcs.Clear(); } }