예제 #1
0
        protected override void OnReceived(EndPoint endPoint, ReadOnlySpan <byte> buffer)
        {
            _logger.Verbose($"Handling OnReceived (EndPoint='{endPoint}', Size={buffer.Length}).");
            if (buffer.Length <= 0)
            {
                ReceiveAsync();
                return;
            }

            // Retrieve the session
            if (!_sessionService.TryGetSession(endPoint, out var session))
            {
                session = _sessionService.OpenSession(this, endPoint);
            }

            // Read the message
            var      bufferReader = new SpanBufferReader(buffer);
            IMessage message;

            try
            {
                var isEncrypted = bufferReader.ReadBool();
                if (isEncrypted)
                {
                    message = _encryptedMessageReader.ReadFrom(
                        ref bufferReader,
                        session.ReceiveKey, session.ReceiveMac
                        );
                }
                else
                {
                    message = _messageReader.ReadFrom(ref bufferReader);
                }
            }
            catch (Exception e)
            {
                _logger.Warning(e, $"Failed to read message (EndPoint='{session.EndPoint}').");
                ReceiveAsync();
                return;
            }

            // Pass it off to a message receiver
            Task.Run(async() =>
            {
                // TODO: This logic should probably be expanded in case of other
                // message receivers being added (i.e. dedicated servers)
                if (message is not IEncryptedMessage)
                {
                    await _handshakeMessageReceiver.OnReceived(session, message).ConfigureAwait(false);
                }
                else
                {
                    await _userMessageReceiver.OnReceived(session, message).ConfigureAwait(false);
                }
            });

            ReceiveAsync();
        }
        public void Signal(ISession session, ReadOnlySpan <byte> buffer)
        {
            var      bufferReader = new SpanBufferReader(buffer);
            IMessage message;

            try
            {
                var isEncrypted = bufferReader.ReadBool();
                if (isEncrypted)
                {
                    if (session.EncryptionParameters is null)
                    {
                        _logger.Warning(
                            "Received an encrypted messsage before any " +
                            "encryption parameters were established " +
                            $"(EndPoint='{session.EndPoint}')."
                            );
                        return;
                    }
                    message = _encryptedMessageReader.ReadFrom(
                        ref bufferReader,
                        session.EncryptionParameters.ReceiveKey,
                        session.EncryptionParameters.ReceiveMac,
                        PacketProperty
                        );
                }
                else
                {
                    message = _messageReader.ReadFrom(ref bufferReader, PacketProperty);
                }
            }
            catch (Exception e)
            {
                _logger.Warning(e, $"Failed to read message (EndPoint='{session.EndPoint}').");
                return;
            }
            Signal(session, message);
        }