Beispiel #1
0
        public void TestClientIdField()
        {
            Span <byte> expectedAsHex = stackalloc byte[] { 0x21, 0x22, 0x23, 0x24 };
            ClientId    expected      = ClientId.ReadFrom(expectedAsHex);

            Assert.Equal(expected, ClientServerMessage.GetClientId(_bytes));
            Assert.Throws <ArgumentException>(() => ClientServerMessage.GetClientId(new Span <byte>(_bytes, 0, 11)));
        }
Beispiel #2
0
        // TODO: [vermorel] Almost but not quite like other 'Iterator' in solution. Align designs.

        /// <summary>
        /// Provides the next unread message.
        /// </summary>
        /// <remarks>
        /// Returned span is only valid until the next call to
        /// <see cref="ReceiveNext"/>.
        /// </remarks>
        public Span <byte> ReceiveNext()
        {
            // Delete first message and copy everything else to the beginning
            var length = InputMessageLength();

            if (length > 0)
            {
                Array.Copy(_bufferIn, length, _bufferIn, 0, _endIn - length);
                _endIn -= length;
            }

            // Try to receive more data from socket
            if (IsConnected && 0 != _socket.Available() && _bufferIn.Length != _endIn)
            {
                _endIn += _socket.Receive(new Span <byte>(_bufferIn).Slice(_endIn));
            }

            length = InputMessageLength();
            if (length > 0)
            {
                var message = new Span <byte>(_bufferIn, 0, length);

                var messageStatus = PassesVerifications(message);

                if (messageStatus != MessageType.EverythingOk)
                {
                    switch (messageStatus)
                    {
                    case MessageType.ClientIdFieldNotEmpty:
                        new Span <byte>(_errorSpan).EmitClientIdFieldNotEmpty(message);
                        _socket.Send(_errorSpan);
                        // see whether a valid message is waiting in the inbox
                        return(ReceiveNext());
                    }
                }
                else // write client ID into message
                {
                    ConnectionId.WriteTo(message.Slice(8));
                }
                return(new Span <byte>(_bufferIn, 0, length));
            }
            else
            {
                return(Span <byte> .Empty);
            }

            // TODO: [vermorel] The intent of this method must be clarified.
            MessageType PassesVerifications(Span <byte> message)
            {
                // Maybe other verifications are going to be added over time
                if (message.Length >= ClientServerMessage.PayloadStart && ClientServerMessage.GetClientId(message).IsSpecified)
                {
                    return(MessageType.ClientIdFieldNotEmpty);
                }

                return(MessageType.EverythingOk);
            }
        }
Beispiel #3
0
        public void SendResponses()
        {
            var toSend = _outbox.Peek();

            while (toSend.Length != 0)
            {
                if (_activeConnections.TryGetValue(ClientServerMessage.GetClientId(toSend), out var client))
                {
                    client.TryWrite(toSend);
                }

                _outbox.Next();
                toSend = _outbox.Peek();
            }
        }