Пример #1
0
 private void SamReaderOnDatagramDataReceived(
     DatagramDataReceivedArgs datagramDataReceivedArgs
     )
 {
     if (_handleDatagrams)
     {
         _datagramDataReceived.OnNext(datagramDataReceivedArgs);
     }
 }
Пример #2
0
 private void SamReaderOnDatagramDataReceived(
     DatagramDataReceivedArgs datagramDataReceivedArgs
 )
 {
     if(_handleDatagrams)
         _datagramDataReceived.OnNext(datagramDataReceivedArgs);
 }
        private async void SamHelperOnDatagramDataReceived(
            DatagramDataReceivedArgs datagramDataReceivedArgs
            )
        {
            try
            {
                using (_stateHelper.GetFuncWrapper())
                {
                    if (
                        datagramDataReceivedArgs.Data.Length
                        > (_settings.MaxBlockSize + 1000)
                        )
                        return;
                    if (
                        _dropDestinations.Contains(
                            datagramDataReceivedArgs.Destination
                            )
                        )
                        return;

                    string fromDestination = datagramDataReceivedArgs.Destination;
                    using (
                        var reader = new EndianBinaryReader(
                            _littleEndianConverter,
                            new MemoryStream(datagramDataReceivedArgs.Data)
                            )
                        )
                    {
                        var blockType = (ReliableDatagramCodes) reader.ReadByte();
                        switch (blockType)
                        {
                            case ReliableDatagramCodes.RawDatagram:
                            {
                                uint messageId = reader.ReadUInt32();
                                uint replyToMessageId = reader.ReadUInt32();
                                byte messageKind = reader.ReadByte();
                                var messageHash = reader.ReadBytesOrThrow(32);
                                var rawData = ReadBytesToEnd(reader);
                                if (
                                    messageHash.SequenceEqual(
                                        GetMessageHash(
                                            messageId,
                                            replyToMessageId,
                                            messageKind,
                                            rawData
                                            )
                                        )
                                    )
                                    RawDatagramReceived.OnNext(
                                        new ReliableMessageReceivedArgs()
                                        {
                                            Data = rawData,
                                            Destination = fromDestination,
                                            MessageId = messageId,
                                            ReplyToMessageId = replyToMessageId,
                                            MessageKind = messageKind
                                        }
                                        );
                                return;
                            }
                            case ReliableDatagramCodes.HandshakeStart:
                            {
                                uint messageId = reader.ReadUInt32();
                                uint replyToMessageId = reader.ReadUInt32();
                                byte messageKind = reader.ReadByte();
                                uint totalMessageSize = reader.ReadUInt32();
                                if (totalMessageSize > _settings.MaxMesageLength)
                                    return;
                                uint blockSize = reader.ReadUInt32();
                                if (blockSize > _settings.MaxBlockSize)
                                    return;
                                var messageHash = reader.ReadBytesOrThrow(32);
                                uint firstBlockSize = reader.ReadUInt32();
                                if (
                                    firstBlockSize == 0
                                    ||
                                    firstBlockSize > _settings.MaxBlockSize
                                    )
                                    return;
                                byte[] firstBlockData
                                    = reader.ReadBytesOrThrow((int) firstBlockSize);
                                HandshakeStartReceived.OnNext(
                                    new HandshakeStartArgs
                                    {
                                        Destination = fromDestination,
                                        BlockSize = blockSize,
                                        MessageId = messageId,
                                        ReplyToMessageId = replyToMessageId,
                                        MessageSize = totalMessageSize,
                                        MessageKind = messageKind,
                                        MessageHash = messageHash,
                                        FirstBlockData = firstBlockData
                                    }
                                    );
                                return;
                            }
                            case ReliableDatagramCodes.MessageStatus:
                            {
                                uint messageId = reader.ReadUInt32();
                                if (!await CheckExistOutMessage(fromDestination, messageId).ConfigureAwait(false))
                                {
                                    return;
                                }
                                var errorCode
                                    = (MessageStatusArgs.MessageStatusCode)
                                        reader.ReadByte();
                                uint blocksReceived = reader.ReadUInt32();
                                MessageStatusReceived.OnNext(
                                    new MessageStatusArgs()
                                    {
                                        Destination
                                            = datagramDataReceivedArgs
                                                .Destination,
                                        MessageId = messageId,
                                        StatusCode = errorCode,
                                        BlocksReceived = blocksReceived
                                    }
                                    );
                                return;
                            }
                            case ReliableDatagramCodes.BlockSend:
                            {
                                uint messageId = reader.ReadUInt32();
                                uint blockId = reader.ReadUInt32();
                                var blockData = ReadBytesToEnd(reader);
                                if (
                                    blockData.Length == 0
                                    || blockData.Length > _settings.MaxBlockSize
                                    )
                                    return;
                                BlockSendReceived.OnNext(new BlockSendArgs()
                                {
                                    Destination = fromDestination,
                                    MessageId = messageId,
                                    BlockId = blockId,
                                    BlockData = blockData
                                });
                                return;
                            }
                            case ReliableDatagramCodes.BlockConfirmation:
                            {
                                uint messageId = reader.ReadUInt32();
                                if (!await CheckExistOutMessage(fromDestination, messageId).ConfigureAwait(false))
                                    return;
                                uint blockId = reader.ReadUInt32();
                                BlockConfirmationReceived.OnNext(
                                    new BlockConfirmationArgs()
                                    {
                                        Destination = fromDestination,
                                        MessageId = messageId,
                                        BlockId = blockId
                                    }
                                    );
                                return;
                            }
                            case ReliableDatagramCodes.GetMessageStatus:
                            {
                                uint messageId = reader.ReadUInt32();
                                GetMessageStatusReceived.OnNext(
                                    new GetMessageStatusArgs()
                                    {
                                        Destination = fromDestination,
                                        MessageId = messageId
                                    }
                                    );
                                return;
                            }
                            case ReliableDatagramCodes.GetProtocolVersion:
                            {
                                GetProtocolVersionReceived.OnNext(
                                    new GetProtocolVersionArgs()
                                    {
                                        Destination = fromDestination
                                    }
                                    );
                                return;
                            }
                            case ReliableDatagramCodes.ProtocolVersion:
                            {
                                uint protocolVersion = reader.ReadUInt32();
                                ProtocolVersionReceived.OnNext(
                                    new ProtocolVersionArgs()
                                    {
                                        Destination = fromDestination,
                                        ProtocolVersion = protocolVersion
                                    }
                                    );
                                return;
                            }
                        }
                    }
                }
            }
            catch (EndOfStreamException exc)
            {
                _log.Error(
                    "SamHelperOnDatagramDataReceived" +
                    " EndOfStreamException '{0}'",
                    exc.ToString()
                );
            }
            catch (OperationCanceledException)
            {
            }
            catch (WrongDisposableObjectStateException)
            {
            }
            catch (Exception exc)
            {
                _log.Error(
                    "SamHelperOnDatagramDataReceived" +
                    " unexpected error '{0}'",
                    exc.ToString()
                    );
            }
        }
        private async void SamHelperOnDatagramDataReceived(
            DatagramDataReceivedArgs datagramDataReceivedArgs
            )
        {
            try
            {
                using (_stateHelper.GetFuncWrapper())
                {
                    if (
                        datagramDataReceivedArgs.Data.Length
                        > (_settings.MaxBlockSize + 1000)
                        )
                    {
                        return;
                    }
                    if (
                        _dropDestinations.Contains(
                            datagramDataReceivedArgs.Destination
                            )
                        )
                    {
                        return;
                    }

                    string fromDestination = datagramDataReceivedArgs.Destination;
                    using (
                        var reader = new EndianBinaryReader(
                            _littleEndianConverter,
                            new MemoryStream(datagramDataReceivedArgs.Data)
                            )
                        )
                    {
                        var blockType = (ReliableDatagramCodes)reader.ReadByte();
                        switch (blockType)
                        {
                        case ReliableDatagramCodes.RawDatagram:
                        {
                            uint messageId        = reader.ReadUInt32();
                            uint replyToMessageId = reader.ReadUInt32();
                            byte messageKind      = reader.ReadByte();
                            var  messageHash      = reader.ReadBytesOrThrow(32);
                            var  rawData          = ReadBytesToEnd(reader);
                            if (
                                messageHash.SequenceEqual(
                                    GetMessageHash(
                                        messageId,
                                        replyToMessageId,
                                        messageKind,
                                        rawData
                                        )
                                    )
                                )
                            {
                                RawDatagramReceived.OnNext(
                                    new ReliableMessageReceivedArgs()
                                    {
                                        Data             = rawData,
                                        Destination      = fromDestination,
                                        MessageId        = messageId,
                                        ReplyToMessageId = replyToMessageId,
                                        MessageKind      = messageKind
                                    }
                                    );
                            }
                            return;
                        }

                        case ReliableDatagramCodes.HandshakeStart:
                        {
                            uint messageId        = reader.ReadUInt32();
                            uint replyToMessageId = reader.ReadUInt32();
                            byte messageKind      = reader.ReadByte();
                            uint totalMessageSize = reader.ReadUInt32();
                            if (totalMessageSize > _settings.MaxMesageLength)
                            {
                                return;
                            }
                            uint blockSize = reader.ReadUInt32();
                            if (blockSize > _settings.MaxBlockSize)
                            {
                                return;
                            }
                            var  messageHash    = reader.ReadBytesOrThrow(32);
                            uint firstBlockSize = reader.ReadUInt32();
                            if (
                                firstBlockSize == 0
                                ||
                                firstBlockSize > _settings.MaxBlockSize
                                )
                            {
                                return;
                            }
                            byte[] firstBlockData
                                = reader.ReadBytesOrThrow((int)firstBlockSize);
                            HandshakeStartReceived.OnNext(
                                new HandshakeStartArgs
                                {
                                    Destination      = fromDestination,
                                    BlockSize        = blockSize,
                                    MessageId        = messageId,
                                    ReplyToMessageId = replyToMessageId,
                                    MessageSize      = totalMessageSize,
                                    MessageKind      = messageKind,
                                    MessageHash      = messageHash,
                                    FirstBlockData   = firstBlockData
                                }
                                );
                            return;
                        }

                        case ReliableDatagramCodes.MessageStatus:
                        {
                            uint messageId = reader.ReadUInt32();
                            if (!await CheckExistOutMessage(fromDestination, messageId).ConfigureAwait(false))
                            {
                                return;
                            }
                            var errorCode
                                = (MessageStatusArgs.MessageStatusCode)
                                  reader.ReadByte();
                            uint blocksReceived = reader.ReadUInt32();
                            MessageStatusReceived.OnNext(
                                new MessageStatusArgs()
                                {
                                    Destination
                                        = datagramDataReceivedArgs
                                          .Destination,
                                    MessageId      = messageId,
                                    StatusCode     = errorCode,
                                    BlocksReceived = blocksReceived
                                }
                                );
                            return;
                        }

                        case ReliableDatagramCodes.BlockSend:
                        {
                            uint messageId = reader.ReadUInt32();
                            uint blockId   = reader.ReadUInt32();
                            var  blockData = ReadBytesToEnd(reader);
                            if (
                                blockData.Length == 0 ||
                                blockData.Length > _settings.MaxBlockSize
                                )
                            {
                                return;
                            }
                            BlockSendReceived.OnNext(new BlockSendArgs()
                                {
                                    Destination = fromDestination,
                                    MessageId   = messageId,
                                    BlockId     = blockId,
                                    BlockData   = blockData
                                });
                            return;
                        }

                        case ReliableDatagramCodes.BlockConfirmation:
                        {
                            uint messageId = reader.ReadUInt32();
                            if (!await CheckExistOutMessage(fromDestination, messageId).ConfigureAwait(false))
                            {
                                return;
                            }
                            uint blockId = reader.ReadUInt32();
                            BlockConfirmationReceived.OnNext(
                                new BlockConfirmationArgs()
                                {
                                    Destination = fromDestination,
                                    MessageId   = messageId,
                                    BlockId     = blockId
                                }
                                );
                            return;
                        }

                        case ReliableDatagramCodes.GetMessageStatus:
                        {
                            uint messageId = reader.ReadUInt32();
                            GetMessageStatusReceived.OnNext(
                                new GetMessageStatusArgs()
                                {
                                    Destination = fromDestination,
                                    MessageId   = messageId
                                }
                                );
                            return;
                        }

                        case ReliableDatagramCodes.GetProtocolVersion:
                        {
                            GetProtocolVersionReceived.OnNext(
                                new GetProtocolVersionArgs()
                                {
                                    Destination = fromDestination
                                }
                                );
                            return;
                        }

                        case ReliableDatagramCodes.ProtocolVersion:
                        {
                            uint protocolVersion = reader.ReadUInt32();
                            ProtocolVersionReceived.OnNext(
                                new ProtocolVersionArgs()
                                {
                                    Destination     = fromDestination,
                                    ProtocolVersion = protocolVersion
                                }
                                );
                            return;
                        }
                        }
                    }
                }
            }
            catch (EndOfStreamException exc)
            {
                _log.Error(
                    "SamHelperOnDatagramDataReceived" +
                    " EndOfStreamException '{0}'",
                    exc.ToString()
                    );
            }
            catch (OperationCanceledException)
            {
            }
            catch (WrongDisposableObjectStateException)
            {
            }
            catch (Exception exc)
            {
                _log.Error(
                    "SamHelperOnDatagramDataReceived" +
                    " unexpected error '{0}'",
                    exc.ToString()
                    );
            }
        }