Exemplo n.º 1
0
        private async Task <bool> ReadContent(HorseMessage message, Stream stream)
        {
            if (message.Length == 0)
            {
                return(true);
            }

            if (message.Content == null)
            {
                message.Content = new MemoryStream();
            }

            ulong left = message.Length;
            ulong blen = (ulong)_buffer.Length;

            do
            {
                int rcount = (int)(left > blen ? blen : left);
                int read   = await stream.ReadAsync(_buffer, 0, rcount);

                if (read == 0)
                {
                    return(false);
                }

                left -= (uint)read;
                await message.Content.WriteAsync(_buffer, 0, read);
            }while (left > 0);

            return(true);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Reads first Hello message from client
        /// </summary>
        private async Task <bool> ProcessFirstMessage(HorseMessage message, IConnectionInfo info, ProtocolHandshakeResult handshakeResult)
        {
            if (message.Type != MessageType.Server || message.ContentType != KnownContentTypes.Hello)
            {
                return(false);
            }

            ConnectionData connectionData = new ConnectionData();

            message.Content.Position = 0;
            await connectionData.ReadFromStream(message.Content);

            HorseServerSocket socket = await _handler.Connected(_server, info, connectionData);

            if (socket == null)
            {
                info.Close();
                return(false);
            }

            info.State             = ConnectionStates.Pipe;
            handshakeResult.Socket = socket;
            _server.HeartbeatManager.Add(socket);

            socket.SetCleanupAction(s =>
            {
                _server.HeartbeatManager.Remove(socket);
                _handler.Disconnected(_server, s);
            });

            return(true);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Handles the connection and reads received HMQ messages
        /// </summary>
        public async Task HandleConnection(IConnectionInfo info, ProtocolHandshakeResult handshakeResult)
        {
            //if user makes a mistake in ready method, we should not interrupt connection handling
            try
            {
                await _handler.Ready(_server, (HorseServerSocket)handshakeResult.Socket);
            }
            catch (Exception e)
            {
                if (_server.Logger != null)
                {
                    _server.Logger.LogException("Unhandled Exception", e);
                }
            }

            HmqReader reader = new HmqReader();

            while (info.Client != null && info.Client.Connected)
            {
                HorseMessage message = await reader.Read(info.GetStream());

                if (message == null)
                {
                    info.Close();
                    return;
                }

                await ProcessMessage(info, message, (HorseServerSocket)handshakeResult.Socket);
            }
        }
Exemplo n.º 4
0
        private Task ProcessMessage(IConnectionInfo info, HorseMessage message, HorseServerSocket socket)
        {
            //if user makes a mistake in received method, we should not interrupt connection handling
            try
            {
                if (socket.SmartHealthCheck)
                {
                    socket.KeepAlive();
                }
                else if (message.Type == MessageType.Pong)
                {
                    socket.KeepAlive();
                }

                return(_handler.Received(_server, info, socket, message));
            }
            catch (Exception e)
            {
                if (_server.Logger != null)
                {
                    _server.Logger.LogException("Unhandled Exception", e);
                }

                return(Task.CompletedTask);
            }
        }
Exemplo n.º 5
0
        private static void WriteContent(MemoryStream ms, HorseMessage message)
        {
            if (message.Length > 0 && message.Content != null)
            {
                message.Content.WriteTo(ms);
            }

            ms.Position = 0;
        }
Exemplo n.º 6
0
        /// <summary>
        /// Sends HMQ message to client
        /// </summary>
        public virtual Task <bool> SendAsync(HorseMessage message, IList <KeyValuePair <string, string> > additionalHeaders = null)
        {
            if (UseUniqueMessageId && string.IsNullOrEmpty(message.MessageId))
            {
                message.SetMessageId(_uniqueIdGenerator.Create());
            }

            byte[] data = HmqWriter.Create(message, additionalHeaders);
            return(SendAsync(data));
        }
Exemplo n.º 7
0
        /// <summary>
        /// Create a response message of the message
        /// </summary>
        public HorseMessage CreateResponse(HorseResultCode status)
        {
            HorseMessage message = new HorseMessage();

            message.HighPriority = Type == MessageType.DirectMessage;
            message.Type         = MessageType.Response;
            message.ContentType  = Convert.ToUInt16(status);
            message.SetMessageId(MessageId);
            message.SetTarget(Type == MessageType.QueueMessage ? Target : Source);

            return(message);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Clones the message
        /// </summary>
        public HorseMessage Clone(bool cloneHeaders, bool cloneContent, string cloneId, List <KeyValuePair <string, string> > additionalHeaders = null)
        {
            HorseMessage clone = new HorseMessage(Type, Target);

            if (!string.IsNullOrEmpty(cloneId))
            {
                clone.SetMessageId(cloneId);
            }

            clone.SetSource(Source);

            clone.HighPriority = HighPriority;
            clone.WaitResponse = WaitResponse;
            clone.ContentType  = ContentType;

            if (cloneHeaders && HasHeader)
            {
                clone.HasHeader   = true;
                clone.HeadersList = new List <KeyValuePair <string, string> >(HeadersList);
            }

            if (additionalHeaders != null && additionalHeaders.Count > 0)
            {
                if (!clone.HasHeader)
                {
                    clone.HasHeader   = true;
                    clone.HeadersList = new List <KeyValuePair <string, string> >(additionalHeaders);
                }
                else
                {
                    clone.HeadersList.AddRange(additionalHeaders);
                }
            }

            if (cloneContent && Content != null && Content.Length > 0)
            {
                Content.Position = 0;
                clone.Content    = new MemoryStream();
                Content.WriteTo(clone.Content);
                clone.Length = Convert.ToUInt64(clone.Content.Length);
            }

            return(clone);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Writes a HMQ message to stream
        /// </summary>
        public static void Write(HorseMessage value, Stream stream, IList <KeyValuePair <string, string> > additionalHeaders = null)
        {
            bool hasAdditionalHeader = additionalHeaders != null && additionalHeaders.Count > 0;

            using MemoryStream ms = new MemoryStream();
            WriteFrame(ms, value, hasAdditionalHeader);

            if (value.HasHeader || hasAdditionalHeader)
            {
                WriteHeader(ms, value, additionalHeaders);
            }

            if (value.Length > 0)
            {
                WriteContent(ms, value);
            }

            ms.WriteTo(stream);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Creates byte array of HMQ message
        /// </summary>
        public static byte[] Create(HorseMessage value, IList <KeyValuePair <string, string> > additionalHeaders = null)
        {
            bool hasAdditionalHeader = additionalHeaders != null && additionalHeaders.Count > 0;

            using MemoryStream ms = new MemoryStream();
            WriteFrame(ms, value, hasAdditionalHeader);

            if (value.HasHeader || hasAdditionalHeader)
            {
                WriteHeader(ms, value, additionalHeaders);
            }

            if (value.Length > 0)
            {
                WriteContent(ms, value);
            }

            return(ms.ToArray());
        }
Exemplo n.º 11
0
        /// <summary>
        /// Reads HMQ message from stream
        /// </summary>
        public async Task <HorseMessage> Read(Stream stream)
        {
            byte[] bytes = new byte[REQUIRED_SIZE];
            bool   done  = await ReadCertainBytes(stream, bytes, 0, REQUIRED_SIZE);

            if (!done)
            {
                return(null);
            }

            HorseMessage message = new HorseMessage();

            done = await ReadFrame(message, bytes, stream);

            if (!done)
            {
                return(null);
            }

            if (message.HasHeader)
            {
                done = await ReadHeader(message, stream);
            }

            if (!done)
            {
                return(null);
            }

            bool success = await ReadContent(message, stream);

            if (!success)
            {
                return(null);
            }

            if (message.Content != null && message.Content.Position > 0)
            {
                message.Content.Position = 0;
            }

            return(message);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Create an acknowledge message of the message
        /// </summary>
        public HorseMessage CreateAcknowledge(string negativeReason = null)
        {
            HorseMessage message = new HorseMessage();

            message.SetMessageId(MessageId);
            message.Type = MessageType.Response;

            if (Type == MessageType.DirectMessage)
            {
                message.HighPriority = true;
                message.SetSource(Target);
                message.SetTarget(Source);
            }
            else
            {
                message.HighPriority = false;
                //target will be queue name
                message.SetTarget(Target);
            }

            if (!string.IsNullOrEmpty(negativeReason))
            {
                message.ContentType = KnownContentTypes.Failed;
                if (!message.HasHeader)
                {
                    message.HasHeader = true;
                }

                if (message.HeadersList == null)
                {
                    message.HeadersList = new List <KeyValuePair <string, string> >();
                }

                message.HeadersList.Add(new KeyValuePair <string, string>(HorseHeaders.NEGATIVE_ACKNOWLEDGE_REASON, negativeReason));
            }
            else
            {
                message.ContentType = Convert.ToUInt16(HorseResultCode.Ok);
            }

            return(message);
        }
Exemplo n.º 13
0
        private static async Task <bool> ReadHeader(HorseMessage message, Stream stream)
        {
            byte[] size = new byte[2];
            bool   read = await ReadCertainBytes(stream, size, 0, size.Length);

            if (!read)
            {
                return(false);
            }

            int headerLength = BitConverter.ToUInt16(size);

            byte[] data = new byte[headerLength];

            read = await ReadCertainBytes(stream, data, 0, data.Length);

            if (!read)
            {
                return(false);
            }

            string[] headers = Encoding.UTF8.GetString(data).Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
            foreach (string header in headers)
            {
                int i = header.IndexOf(':');
                if (i < 1)
                {
                    continue;
                }

                string key   = header.Substring(0, i);
                string value = header.Substring(i + 1);
                message.HeadersList.Add(new KeyValuePair <string, string>(key, value));
            }

            return(true);
        }
Exemplo n.º 14
0
        private static void WriteHeader(MemoryStream ms, HorseMessage message, IList <KeyValuePair <string, string> > additionalHeaders)
        {
            using MemoryStream headerStream = new MemoryStream();

            if (message.HeadersList != null)
            {
                foreach (KeyValuePair <string, string> pair in message.HeadersList)
                {
                    headerStream.Write(Encoding.UTF8.GetBytes(pair.Key + ":" + pair.Value + "\r\n"));
                }
            }

            if (additionalHeaders != null)
            {
                foreach (KeyValuePair <string, string> pair in additionalHeaders)
                {
                    headerStream.Write(Encoding.UTF8.GetBytes(pair.Key + ":" + pair.Value + "\r\n"));
                }
            }

            ms.Write(BitConverter.GetBytes((ushort)headerStream.Length));
            headerStream.Position = 0;
            headerStream.WriteTo(ms);
        }
Exemplo n.º 15
0
        /// <summary>
        /// Checks if received data is a HMQ protocol message
        /// </summary>
        public async Task <ProtocolHandshakeResult> Handshake(IConnectionInfo info, byte[] data)
        {
            ProtocolHandshakeResult result = new ProtocolHandshakeResult();

            if (data.Length < 8)
            {
                return(await Task.FromResult(result));
            }

            ProtocolVersion version = CheckProtocol(data);

            result.Accepted = version != ProtocolVersion.Unknown;
            if (!result.Accepted)
            {
                return(result);
            }

            HmqReader    reader  = new HmqReader();
            HorseMessage message = await reader.Read(info.GetStream());

            //sends protocol message
            await info.GetStream().WriteAsync(PredefinedMessages.PROTOCOL_BYTES_V2);

            bool alive = await ProcessFirstMessage(message, info, result);

            if (!alive)
            {
                return(result);
            }

            result.PipeConnection = true;
            info.State            = ConnectionStates.Pipe;
            info.Protocol         = this;

            return(result);
        }
Exemplo n.º 16
0
        private static void WriteFrame(MemoryStream ms, HorseMessage message, bool hasAdditionalHeaders)
        {
            byte proto = (byte)message.Type;

            if (message.WaitResponse)
            {
                proto += 128;
            }

            if (message.HighPriority)
            {
                proto += 64;
            }

            if (message.HasHeader || hasAdditionalHeaders)
            {
                proto += 32;
            }

            ms.WriteByte(proto);
            byte reserved = 0;

            ms.WriteByte(reserved);
            ms.WriteByte((byte)message.MessageIdLength);
            ms.WriteByte((byte)message.SourceLength);
            ms.WriteByte((byte)message.TargetLength);

            ms.Write(BitConverter.GetBytes(message.ContentType));

            if (message.Content != null && message.Length == 0)
            {
                message.Length = (ulong)message.Content.Length;
            }

            if (message.Length < 253)
            {
                ms.WriteByte((byte)message.Length);
            }
            else if (message.Length <= ushort.MaxValue)
            {
                ms.WriteByte(253);
                ms.Write(BitConverter.GetBytes((ushort)message.Length));
            }
            else if (message.Length <= uint.MaxValue)
            {
                ms.WriteByte(254);
                ms.Write(BitConverter.GetBytes((uint)message.Length));
            }
            else
            {
                ms.WriteByte(255);
                ms.Write(BitConverter.GetBytes(message.Length));
            }

            if (message.MessageIdLength > 0)
            {
                byte[] bytes = Encoding.UTF8.GetBytes(message.MessageId);
                ms.Write(bytes);
            }

            if (message.SourceLength > 0)
            {
                byte[] bytes = Encoding.UTF8.GetBytes(message.Source);
                ms.Write(bytes);
            }

            if (message.TargetLength > 0)
            {
                byte[] bytes = Encoding.UTF8.GetBytes(message.Target);
                ms.Write(bytes);
            }
        }
Exemplo n.º 17
0
 /// <summary>
 /// Creates byte array of only HMQ message frame
 /// </summary>
 public static byte[] CreateFrame(HorseMessage value)
 {
     using MemoryStream ms = new MemoryStream();
     WriteFrame(ms, value, false);
     return(ms.ToArray());
 }
Exemplo n.º 18
0
 /// <summary>
 /// Creates byte array of only HMQ message content
 /// </summary>
 public static byte[] CreateContent(HorseMessage value)
 {
     using MemoryStream ms = new MemoryStream();
     WriteContent(ms, value);
     return(ms.ToArray());
 }
Exemplo n.º 19
0
        private async Task <bool> ReadFrame(HorseMessage message, byte[] bytes, Stream stream)
        {
            byte proto = bytes[0];

            if (proto >= 128)
            {
                message.WaitResponse = true;
                proto -= 128;
            }

            if (proto >= 64)
            {
                message.HighPriority = true;
                proto -= 64;
            }

            if (proto >= 32)
            {
                proto       -= 32;
                message.Type = (MessageType)proto;

                if (message.Type != MessageType.Ping && message.Type != MessageType.Pong)
                {
                    message.HasHeader   = true;
                    message.HeadersList = new List <KeyValuePair <string, string> >();
                }
            }
            else
            {
                message.Type = (MessageType)proto;
            }

            // bytes[1] is reserved

            message.MessageIdLength = bytes[2];
            message.SourceLength    = bytes[3];
            message.TargetLength    = bytes[4];

            message.ContentType = BitConverter.ToUInt16(bytes, 5);

            byte length = bytes[7];

            if (length == 253)
            {
                bool done = await ReadCertainBytes(stream, bytes, 0, 2);

                if (!done)
                {
                    return(false);
                }

                message.Length = BitConverter.ToUInt16(bytes, 0);
            }
            else if (length == 254)
            {
                bool done = await ReadCertainBytes(stream, bytes, 0, 4);

                if (!done)
                {
                    return(false);
                }

                message.Length = BitConverter.ToUInt32(bytes, 0);
            }
            else if (length == 255)
            {
                byte[] b    = new byte[8];
                bool   done = await ReadCertainBytes(stream, b, 0, 8);

                if (!done)
                {
                    return(false);
                }

                message.Length = BitConverter.ToUInt64(b, 0);
            }
            else
            {
                message.Length = length;
            }

            if (message.MessageIdLength > 0)
            {
                message.MessageId = await ReadOctetSizeData(stream, message.MessageIdLength);
            }

            if (message.SourceLength > 0)
            {
                message.Source = await ReadOctetSizeData(stream, message.SourceLength);
            }

            if (message.TargetLength > 0)
            {
                message.Target = await ReadOctetSizeData(stream, message.TargetLength);
            }

            return(true);
        }