示例#1
0
        private void ReceivingThreadFunction(CancellationToken cancellationToken)
        {
            //providing raw message reader with limited access to tcp stream that cancels when
            //token is used
            RawMessageReader reader = new RawMessageReader(
                (buffer, count, offset) =>
            {
                var resTask = _tcpStream.ReadAsync(buffer, offset, count, cancellationToken);
                resTask.Wait();
                return(resTask.Result);
            }
                );

            //message reading loop
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    string  nextMessageString = GetNextMessageAsString(reader);
                    Message nextMessage       = ParseMessage(nextMessageString);
                    CallMessageCallback(nextMessage);
                }
                catch (OperationCanceledException)
                {
                    break;
                }
                catch (Exception e)
                {
                    if (_errorCallback != null)
                    {
                        _errorCallback.Invoke(e);
                    }
                }
            }
        }
        /// <summary>
        /// Reads and parses protocol message from the network stream.
        /// </summary>
        /// <returns>Parsed protocol message or null if the function fails.</returns>
        public async Task <Message> ReceiveMessageAsync()
        {
            log.Trace("()");

            Message res = null;

            using (CancellationTokenSource readTimeoutTokenSource = new CancellationTokenSource(60000),
                   timeoutShutdownTokenSource = CancellationTokenSource.CreateLinkedTokenSource(readTimeoutTokenSource.Token, shutdownCancellationToken))
            {
                RawMessageReader messageReader = new RawMessageReader(Stream);
                RawMessageResult rawMessage    = await messageReader.ReceiveMessageAsync(timeoutShutdownTokenSource.Token);

                if (rawMessage.Data != null)
                {
                    res = CreateMessageFromRawData(rawMessage.Data);
                    if (res.MessageTypeCase == Message.MessageTypeOneofCase.Response)
                    {
                        lastResponseStatus  = res.Response.Status;
                        lastResponseDetails = res.Response.Details;
                    }
                }
            }

            ForceDisconnect = res == null;

            log.Trace("(-):ForceDisconnect={0}", ForceDisconnect, res != null ? "Message" : "null");
            return(res);
        }
        public void TestGetNextMessageAsStringCanReadStringOfLength8KiB()
        {
            //given
            StringBuilder sb = new StringBuilder();

            for (int i = 0; i < 8192; i++)
            {
                sb.Append("a");
            }
            string expected = sb.ToString();

            byte[] inputBuffer = new byte[8194];

            byte[] textBytes   = Encoding.UTF8.GetBytes(expected);
            byte[] lengthBytes = BitConverter.GetBytes((ushort)textBytes.Length);
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(lengthBytes);
            }
            Array.Copy(lengthBytes, 0, inputBuffer, 0, 2);
            Array.Copy(textBytes, 0, inputBuffer, 2, textBytes.Length);
            Stream stream = new MemoryStream(inputBuffer);

            RawMessageReader reader = new RawMessageReader(
                (buffer, count, offset) => stream.Read(buffer, offset, count));

            //when
            String actual = reader.GetNextMessageAsString();

            //then
            Assert.AreEqual(expected, actual);

            stream.Dispose();
        }
        public void TestGetNextMessageAsStringCanReadEmptyString()
        {
            //given
            String expected = "";

            byte[] inputBuffer = new byte[20];

            byte[] textBytes   = Encoding.UTF8.GetBytes(expected);
            byte[] lengthBytes = BitConverter.GetBytes((ushort)textBytes.Length);
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(lengthBytes);
            }
            Array.Copy(lengthBytes, 0, inputBuffer, 0, 2);
            Array.Copy(textBytes, 0, inputBuffer, 2, textBytes.Length);
            Stream stream = new MemoryStream(inputBuffer);

            RawMessageReader reader = new RawMessageReader(
                (buffer, count, offset) => stream.Read(buffer, offset, count));

            //when
            String actual = reader.GetNextMessageAsString();

            //then
            Assert.AreEqual(expected, actual);

            stream.Dispose();
        }
示例#5
0
 private string GetNextMessageAsString(RawMessageReader reader)
 {
     try
     {
         return(reader.GetNextMessageAsString());
     }
     catch (Exception e)
     {
         throw new DisconnectedException(e);
     }
 }
        /// <summary>
        /// Reads messages from the client stream and processes them in a loop until the client disconnects
        /// or until an action (such as a protocol violation) that leads to disconnecting of the client occurs.
        /// </summary>
        public async Task ReceiveMessageLoop()
        {
            log.Trace("()");

            try
            {
                if (UseTls)
                {
                    SslStream  sslStream = (SslStream)Stream;
                    ConfigBase config    = (ConfigBase)Base.ComponentDictionary[ConfigBase.ComponentName];
                    await sslStream.AuthenticateAsServerAsync((X509Certificate)config.Settings["TcpServerTlsCertificate"], false, SslProtocols.Tls12, false);
                }

                RawMessageReader messageReader = new RawMessageReader(Stream);
                while (!shutdownSignaling.IsShutdown)
                {
                    RawMessageResult rawMessage = await messageReader.ReceiveMessageAsync(shutdownSignaling.ShutdownCancellationTokenSource.Token);

                    bool disconnect        = rawMessage.Data == null;
                    bool protocolViolation = rawMessage.ProtocolViolation;
                    if (rawMessage.Data != null)
                    {
                        IProtocolMessage message = CreateMessageFromRawData(rawMessage.Data);
                        if (message != null)
                        {
                            disconnect = !await messageProcessor.ProcessMessageAsync(this, message);
                        }
                        else
                        {
                            protocolViolation = true;
                        }
                    }

                    if (protocolViolation)
                    {
                        await messageProcessor.SendProtocolViolation(this);

                        break;
                    }

                    if (disconnect)
                    {
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }

            log.Trace("(-)");
        }
        public void TestGetNextMessageAsStringThrowsExceptionOnInvalidRead()
        {
            //given

            var stream = new MemoryStream(new byte[] { 1 });
            RawMessageReader reader = new RawMessageReader(
                (buffer, count, offset) => stream.Read(buffer, offset, count));

            //when
            String result = reader.GetNextMessageAsString();

            //then
            //throws exception

            stream.Dispose();
        }
示例#8
0
        /// <summary>
        /// Reads messages from the client stream and processes them in a loop until the client disconnects
        /// or until an action (such as a protocol violation) that leads to disconnecting of the client occurs.
        /// </summary>
        /// <param name="Client">TCP client.</param>
        /// <param name="MessageBuilder">Client's message builder.</param>
        public async Task ReceiveMessageLoop(TcpClient Client, MessageBuilderLocNet MessageBuilder)
        {
            log.Trace("()");

            try
            {
                NetworkStream    stream        = Client.GetStream();
                RawMessageReader messageReader = new RawMessageReader(stream);
                while (!isShutdown)
                {
                    RawMessageResult rawMessage = await messageReader.ReceiveMessageAsync(shutdownCancellationTokenSource.Token);

                    bool disconnect        = rawMessage.Data == null;
                    bool protocolViolation = rawMessage.ProtocolViolation;
                    if (rawMessage.Data != null)
                    {
                        Message message = CreateMessageFromRawData(rawMessage.Data);
                        if (message != null)
                        {
                            disconnect = !await ProcessMessageAsync(Client, MessageBuilder, message);
                        }
                        else
                        {
                            protocolViolation = true;
                        }
                    }

                    if (protocolViolation)
                    {
                        await SendProtocolViolation(Client);

                        break;
                    }

                    if (disconnect)
                    {
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }

            log.Trace("(-)");
        }
示例#9
0
        /// <summary>
        /// Attempts to connect to LOC server in a loop.
        /// </summary>
        /// <returns>true if the function succeeded, false if connection was established before the component shutdown.</returns>
        public override async Task <bool> ConnectAsync()
        {
            log.Trace("()");
            bool res = false;

            // Close TCP connection if it is connected and reset client.
            IPEndPoint locEndPoint = (IPEndPoint)config.Settings["LocEndPoint"];

            SetRemoteEndPoint(locEndPoint);

            while (!res && !shutdownSignaling.IsShutdown)
            {
                log.Trace("Connecting to LOC server '{0}'.", locEndPoint);
                if (await base.ConnectAsync())
                {
                    messageReader = new RawMessageReader(Stream);
                    res           = true;
                }
                else
                {
                    log.Warn("Unable to connect to LOC server '{0}', waiting 10 seconds and then retrying.", locEndPoint);

                    // On Ubuntu we get exception "Sockets on this platform are invalid for use after a failed connection attempt"
                    // when we try to reconnect to the same IP:port again, after it failed for the first time.
                    // We have to close the socket and initialize it again to be able to connect.
                    SetRemoteEndPoint(locEndPoint);

                    try
                    {
                        await Task.Delay(10000, shutdownSignaling.ShutdownCancellationTokenSource.Token);
                    }
                    catch
                    {
                        // Catch cancellation exception.
                    }
                }
            }

            log.Trace("(-):{0}", res);
            return(res);
        }