public GameClient(string address, int port) { _udp = new UdpClient(0) { Client = { Blocking = false } }; _target = new IPEndPoint(IPAddress.Parse(address), port); _server = new NetworkConnection(_udp, _target); _server.MessageReceived += (fromAddr, message) => MessageReceived?.Invoke(fromAddr, message); _server.ClientDisconnected += (fromAddr) => ServerDisconnected?.Invoke(fromAddr); _server.MessageAcked += (fromAddr, message) => MessageAcked?.Invoke(fromAddr, message); _server.MessageLost += (fromAddr, message) => MessageLost?.Invoke(fromAddr, message); _reliable = new ReliableConnection(_server); _reliable.ReliableMessageRecieved += (fromAddr, message) => ReliableMessageReceived?.Invoke(fromAddr, message); }
public ReliableSamHelper( ISamHelper samHelper, ReliableSamHelperSettings settings ) { if (samHelper == null) { throw new ArgumentNullException( MyNameof.GetLocalVarName(() => samHelper)); } if (settings == null) { throw new ArgumentNullException( MyNameof.GetLocalVarName(() => settings)); } _samHelper = samHelper; _settings = settings; var rng = new Random(DateTime.UtcNow.Millisecond); _nextOutMessageId = (uint)rng.Next(int.MaxValue); RawDatagramReceived.ObserveOn(TaskPoolScheduler.Default).Subscribe(args => _log.Trace( "{5} recv raw datagram of {0} bytes " + "from {1} id={2}, rid={3}, kind={6}, ansiS='{4}'", args.Data.Length, args.Destination.Substring(0, 20), args.MessageId, args.ReplyToMessageId, Encoding.ASCII.GetString(args.Data), _reliableSamHelperGuid.ToString().Substring(0, 5), args.MessageKind )); ReliableMessageReceived.ObserveOn(TaskPoolScheduler.Default).Subscribe(args => _log.Trace( "{4} recv reliable message of {0} bytes " + "from {1} id={2}, rid={3}, kind={5}", args.Data.Length, args.Destination.Substring(0, 20), args.MessageId, args.ReplyToMessageId, _reliableSamHelperGuid.ToString().Substring(0, 5), args.MessageKind ) ); _subscriptions.AddRange( new[] { _samHelper.DatagramDataReceived.ObserveOn(TaskPoolScheduler.Default).Subscribe( SamHelperOnDatagramDataReceived ), GetProtocolVersionReceived.ObserveOn(TaskPoolScheduler.Default).Subscribe( OnGetProtocolVersionReceived ), HandshakeStartReceived.ObserveOn(TaskPoolScheduler.Default).Subscribe( OnHandshakeStartReceived ), GetMessageStatusReceived.ObserveOn(TaskPoolScheduler.Default).Subscribe( OnGetMessageStatusReceived ), BlockSendReceived.ObserveOn(TaskPoolScheduler.Default).Subscribe( OnBlockSendReceived ), Observable.Interval(TimeSpan.FromSeconds(20.0d)).ObserveOn(TaskPoolScheduler.Default).Subscribe( IntervalCleanupAction ) } ); _stateHelper.SetInitializedState(); }
private void HandleNewClientConnection(IPEndPoint clientAddr) { _clients[clientAddr] = new NetworkConnection(_udp, clientAddr); _clients[clientAddr].MessageReceived += (fromAddr, message) => MessageReceived?.Invoke(fromAddr, message); _clients[clientAddr].ClientDisconnected += (fromAddr) => { _clients.Remove(fromAddr); _reliableClients.Remove(fromAddr); ClientDisconnected?.Invoke(fromAddr); }; _clients[clientAddr].MessageAcked += (fromAddr, message) => MessageAcked?.Invoke(fromAddr, message); _clients[clientAddr].MessageLost += (fromAddr, message) => MessageLost?.Invoke(fromAddr, message); _reliableClients[clientAddr] = new ReliableConnection(_clients[clientAddr]); _reliableClients[clientAddr].ReliableMessageRecieved += (fromAddr, message) => ReliableMessageReceived?.Invoke(fromAddr, message); ClientConnected?.Invoke(clientAddr); }
private async void OnBlockSendReceived( BlockSendArgs blockSendArgs ) { try { using (_stateHelper.GetFuncWrapper()) { string fromDestination = blockSendArgs.Destination; if (_dropDestinations.Contains(fromDestination)) { return; } if (!SamHelper.IsDestinationStringValid(fromDestination)) { return; } DestinationInfo destinationInfo; using (await _destinationDbLockSem.GetDisposable().ConfigureAwait(false)) { if ( !_destinationDb.ContainsKey( blockSendArgs.Destination ) ) { return; } destinationInfo = _destinationDb[blockSendArgs.Destination]; } InMessageInfo inMessageInfo; using (await destinationInfo.InMessagesDbLockSem.GetDisposable().ConfigureAwait(false)) { if ( !destinationInfo.InMessagesDb.ContainsKey( blockSendArgs.MessageId ) ) { return; } inMessageInfo = destinationInfo.InMessagesDb[ blockSendArgs.MessageId ]; } if ( inMessageInfo.Status == InMessageStatus.AllBlocksReceived ) { return; } if (inMessageInfo.BlockCount > 1) { await SendBlockConfirmation( fromDestination, blockSendArgs.MessageId, blockSendArgs.BlockId ).ConfigureAwait(false); } if ( await inMessageInfo.ReceiveBlock( blockSendArgs.BlockId, blockSendArgs.BlockData ).ConfigureAwait(false) ) { var allData = new List <byte>( (int)inMessageInfo.MessageSize ); foreach ( byte[] blockData in inMessageInfo.ReceivedData ) { allData.AddRange(blockData); } var dataArray = allData.ToArray(); if ( inMessageInfo.MessageHash.SequenceEqual( GetMessageHash( blockSendArgs.MessageId, inMessageInfo.ReplyToMessageId, inMessageInfo.MessageKind, dataArray ) ) ) { ReliableMessageReceived.OnNext( new ReliableMessageReceivedArgs() { Destination = fromDestination, Data = allData.ToArray(), MessageId = blockSendArgs.MessageId, ReplyToMessageId = inMessageInfo.ReplyToMessageId, MessageKind = inMessageInfo.MessageKind } ); } await inMessageInfo.FlushBlocks().ConfigureAwait(false); } } } catch (OperationCanceledException) { } catch (WrongDisposableObjectStateException) { } catch (Exception exc) { _log.Error( "OnBlockSendReceived" + " unexpected error '{0}'", exc.ToString() ); } }