/// <inheritdoc /> public SessionMessageContext(ManagedClientSession <TPayloadWriteType, TPayloadReadType> session, NetworkIncomingMessage <TPayloadReadType> message) { if (session == null) { throw new ArgumentNullException(nameof(session)); } if (message == null) { throw new ArgumentNullException(nameof(message)); } Session = session; Message = message; }
private async Task ManualStartClientConnectionLoop(TcpClient client, IManagedNetworkClient <TPayloadReadType, TPayloadWriteType> internalNetworkClient, ManagedClientSession <TPayloadReadType, TPayloadWriteType> networkSession) { //So that sessions invoking the disconnection can internally disconnect to networkSession.OnSessionDisconnection += async(source, args) => await internalNetworkClient.DisconnectAsync(0).ConfigureAwait(false); //TODO: Better way to syncronize the strategies used? var dispatchingStrategy = new InPlaceAsyncLockedNetworkMessageDispatchingStrategy <TPayloadReadType, TPayloadWriteType>(); while (client.Connected && internalNetworkClient.isConnected) { NetworkIncomingMessage <TPayloadWriteType> message = await internalNetworkClient.ReadMessageAsync(CancellationToken.None) .ConfigureAwait(false); //We don't want to stop the client just because an exception occurred. try { //TODO: This will work for World of Warcraft since it requires no more than one packet //from the same client be handled at one time. However it limits throughput and maybe we should //handle this at a different level instead. await dispatchingStrategy.DispatchNetworkMessage(new SessionMessageContext <TPayloadReadType, TPayloadWriteType>(networkSession, message)) .ConfigureAwait(false); } catch (Exception e) { //TODO: Remove this console log Logger.Error($"[Error]: {e.Message}\n\nStack: {e.StackTrace}"); } } client.Dispose(); //TODO: Should we tell the client something when it ends? await networkSession.DisconnectClientSession() .ConfigureAwait(false); }