Esempio n. 1
0
 /// <summary>
 /// Creates a new message reader with the specified message to read and the specified encoding.
 /// </summary>
 /// <param name="initialMessage">Message to read.</param>
 /// <param name="encoding">Encoding to use for string interpretation.</param>
 public MqMessageReader(MqMessage initialMessage, Encoding encoding) : base(Stream.Null)
 {
     _encoding        = encoding;
     _decoder         = _encoding.GetDecoder();
     _twoBytesPerChar = encoding is UnicodeEncoding;
     Message          = initialMessage;
 }
 /// <summary>
 /// Adds an existing message's frames to this message.
 /// </summary>
 /// <param name="message">Message to add.</param>
 public void Add(MqMessage message)
 {
     foreach (var frame in message)
     {
         _frames.Add(frame);
     }
 }
        /// <summary>
        /// Deep copies this message with deep copied frames.
        /// </summary>
        /// <returns>Deep copied message.</returns>
        public MqMessage Clone()
        {
            var message = new MqMessage();

            foreach (var frame in _frames)
            {
                message.Add(frame.Clone());
            }

            return(message);
        }
        /// <summary>
        /// Shallow copies this message with shallow copied frames.
        /// </summary>
        /// <returns>Shallow copied message.</returns>
        public MqMessage ShallowCopy()
        {
            var message = new MqMessage();

            foreach (var frame in _frames)
            {
                message.Add(frame.ShallowCopy());
            }

            return(message);
        }
        /// <summary>
        /// Collects all the generated frames and outputs them as a single message.
        /// </summary>
        /// <param name="clearBuilder">Optionally clear this builder and prepare for a new message.</param>
        /// <returns>Message containing all frames.</returns>
        public MqMessage ToMessage(bool clearBuilder)
        {
            FinalizeFrame();
            var message = new MqMessage();

            message.AddRange(_frames);
            message.PrepareSend();

            if (clearBuilder)
            {
                Clear();
            }

            return(message);
        }
        /// <summary>
        /// Sends a message to the session's client.
        /// </summary>
        /// <param name="message">Message to send.</param>
        public void Send(MqMessage message)
        {
            if (message.Count == 0)
            {
                return;
            }
            if (CurrentState != State.Connected)
            {
                return;
            }

            lock (_outboxLock)
            {
                _outbox.Enqueue(message);
            }

            if (_outboxTask == null || _outboxTask.IsCompleted)
            {
                _outboxTask = Task.Run((Action)ProcessOutbox);
            }
        }
        /// <summary>
        /// Closes this session with the specified reason.
        /// Notifies the recipient connection the reason for the session's closure.
        /// </summary>
        /// <param name="reason">Reason for closing this session.</param>
        public override void Close(SocketCloseReason reason)
        {
            if (CurrentState == State.Closed)
            {
                return;
            }

            MqFrame closeFrame = null;

            if (CurrentState == State.Connected)
            {
                CurrentState = State.Closing;

                closeFrame = CreateFrame(new byte[2], MqFrameType.Command);

                closeFrame.Write(0, (byte)0);
                closeFrame.Write(1, (byte)reason);
            }

            // If we are passed a closing frame, then send it to the other connection.
            if (closeFrame != null)
            {
                MqMessage msg;
                if (_outbox.IsEmpty == false)
                {
                    while (_outbox.TryDequeue(out msg))
                    {
                    }
                }

                msg = new MqMessage(closeFrame);
                _outbox.Enqueue(msg);

                // Process the last bit of data.
                ProcessOutbox();
            }

            base.Close(reason);
        }
        /// <summary>
        /// Internal method called by the Postmaster on a different thread to process all bytes in the inbox.
        /// </summary>
        /// <returns>True if incoming queue was processed; False if nothing was available for process.</returns>
        private void ProcessIncomingQueue()
        {
            if (_processMessage == null)
            {
                _processMessage = new MqMessage();
            }

            Queue <MqMessage> messages = null;

            byte[] buffer;
            while (_inboxBytes.TryDequeue(out buffer))
            {
                try
                {
                    _frameBuilder.Write(buffer, 0, buffer.Length);
                }
                catch (InvalidDataException)
                {
                    //logger.Error(ex, "Connector {0}: Client send invalid data.", Connection.Id);

                    Close(SocketCloseReason.ProtocolError);
                    break;
                }

                var frameCount = _frameBuilder.Frames.Count;
                //logger.Debug("Connector {0}: Parsed {1} frames.", Connection.Id, frame_count);

                for (var i = 0; i < frameCount; i++)
                {
                    var frame = _frameBuilder.Frames.Dequeue();

                    // Do nothing if this is a ping frame.
                    if (frame.FrameType == MqFrameType.Ping)
                    {
                        if (BaseSocket.Mode == SocketMode.Server)
                        {
                            // Re-send ping frame back to the client to refresh client connection timeout timer.
                            Send(CreateFrame(null, MqFrameType.Ping));
                        }
                        continue;
                    }

                    // Determine if this frame is a command type.  If it is, process it and don't add it to the message.
                    if (frame.FrameType == MqFrameType.Command)
                    {
                        ProcessCommand(frame);
                        continue;
                    }

                    _processMessage.Add(frame);

                    if (frame.FrameType != MqFrameType.EmptyLast && frame.FrameType != MqFrameType.Last)
                    {
                        continue;
                    }

                    if (messages == null)
                    {
                        messages = new Queue <MqMessage>();
                    }

                    messages.Enqueue(_processMessage);
                    _processMessage = new MqMessage();
                }
            }

            if (messages == null)
            {
                return;
            }


            OnIncomingMessage(this, new IncomingMessageEventArgs <TSession, TConfig>(messages, (TSession)this));

            lock (_inboxLock)
            {
                if (_inboxBytes.IsEmpty == false)
                {
                    _inboxTask = Task.Run((Action)ProcessIncomingQueue);
                }
            }
        }
Esempio n. 9
0
 /// <summary>
 /// Creates a new message reader with the specified message to read and the default encoding of UTF8.
 /// </summary>
 /// <param name="initialMessage">Message to read.</param>
 public MqMessageReader(MqMessage initialMessage) : this(initialMessage, Encoding.UTF8)
 {
 }
Esempio n. 10
0
 /// <summary>
 /// Adds a message to the outbox to be processed.
 /// Empty messages will be ignored.
 /// </summary>
 /// <param name="message">Message to send.</param>
 public void Send(MqMessage message)
 {
     // Send the outgoing message to the session to be processed by the postmaster.
     Session.Send(message);
 }
 /// <summary>
 /// Appends an existing message to this message.
 /// </summary>
 /// <param name="value">Value to write to the message.</param>
 public void Write(MqMessage value)
 {
     InternalFinalizeFrame();
     _frames.AddRange(value);
 }