/// <summary>
        /// Transmit a byte-array of data over this socket, block until frame is sent.
        /// </summary>
        /// <param name="socket">the ISend to transmit on</param>
        /// <param name="data">the byte-array of data to send.</param>
        /// <param name="length">the number of bytes to send from <paramref name="data"/>.</param>
        /// <param name="more">set this flag to true to signal that you will be immediately sending another frame (optional: default is false)</param>
        public static void SendFrame(this ISend socket, byte[] data, int length, bool more = false)
        {
            var frame = new Frame(length);
            Buffer.BlockCopy(data, 0, frame.Data, 0, length);
            frame.More = more;

            socket.SendFrame(ref frame);
            frame.Close();
        }
        /// <summary>
        /// Receive a single frame from <paramref cref="socket"/>, blocking until one arrives.
        /// Indicate whether further frames exist via <paramref name="more"/>.
        /// </summary>
        /// <param name="socket">The socket to receive from.</param>
        /// <param name="more"><c>true</c> if another frame of the same message follows, otherwise <c>false</c>.</param>
        /// <returns>The content of the received message frame.</returns>        
        public static byte[] ReceiveFrameBytes(this IReceive socket, out bool more)
        {
            var frame = new Frame();

            socket.ReceiveFrame(ref frame);

            var data = frame.CloneData();

            more = frame.More;

            frame.Close();
            return data;
        }
        /// <summary>
        /// Transmit a string over this socket, block until frame is sent.
        /// </summary>
        /// <param name="socket">the ISend to transmit on</param>
        /// <param name="message">the string to send</param>        
        /// <param name="more">set this flag to true to signal that you will be immediately sending another frame (optional: default is false)</param>
        public static void SendFrame(this ISend socket, string message, bool more = false)
        {
            // Count the number of bytes required to encode the string.
            // Note that non-ASCII strings may not have an equal number of characters
            // and bytes. The encoding must be queried for this answer.
            // With this number, request a buffer from the pool.
            var frame = new Frame(SendReceiveConstants.DefaultEncoding.GetByteCount(message));
            frame.More = more;

            // Encode the string into the buffer
            SendReceiveConstants.DefaultEncoding.GetBytes(message, 0, message.Length, frame.Data, 0);

            socket.SendFrame(ref frame);
            frame.Close();
        }
        /// <summary>
        /// Receive a single frame from <paramref cref="socket"/>, blocking until one arrives.
        /// Indicate whether further frames exist via <paramref name="more"/>.
        /// </summary>
        /// <param name="socket">The socket to receive from.</param>        
        /// <param name="bytes">Array to populate with the frame data. If pre-allocated and large enough the allocated array will be used. Otherwise new array will be allocated.</param>                
        /// <param name="length">The length of the frame receieved.</param>
        /// <param name="more"><c>true</c> if another frame of the same message follows, otherwise <c>false</c>.</param>
        public static void ReceiveFrameBytes(this IReceive socket, ref byte[] bytes, out int length, out bool more)
        {
            var frame = new Frame();
            socket.ReceiveFrame(ref frame);

            if (bytes != null && bytes.Length >= frame.Length)
                frame.CopyDataTo(bytes);
            else
                bytes = frame.CloneData();

            length = frame.Length;
            more = frame.More;

            frame.Close();
        }
 /// <summary>
 /// Block until the frame is can be sent.
 /// </summary>
 /// <remarks>
 /// The call  blocks until the frame can be sent and cannot be interrupted. 
 /// Wether the frame can be sent depends on the socket type.
 /// </remarks>
 /// <param name="socket">The socket to send the message on.</param>
 /// <param name="frame">An object with message's data to send.</param>        
 public static void SendFrame(this ISend socket, ref Frame frame)
 {
     var result = socket.TrySendFrame(ref frame, Timeout.InfiniteTimeSpan);
     Debug.Assert(result);
 }
        /// <summary>
        /// Attempt to transmit a single frame on <paramref cref="socket"/>.
        /// If message cannot be sent within <paramref name="timeout"/>, return <c>false</c>.
        /// </summary>
        /// <param name="socket">the ISend to transmit on</param>
        /// <param name="timeout">The maximum period of time to try to send a message.</param>
        /// <param name="data">the byte-array of data to send.</param>        
        /// <param name="length">the number of bytes to send from <paramref name="data"/>.</param>
        /// <param name="more">set this flag to true to signal that you will be immediately sending another frame (optional: default is false)</param>
        /// <returns><c>true</c> if a message was available, otherwise <c>false</c>.</returns>
        public static bool TrySendFrame(this ISend socket, TimeSpan timeout, byte[] data, int length, bool more = false)
        {
            var frame = new Frame(length);
            Buffer.BlockCopy(data, 0, frame.Data, 0, length);
            frame.More = more;

            if (!socket.TrySendFrame(ref frame, timeout))
            {
                frame.Close();
                return false;
            }

            frame.Close();
            return true;
        }
Exemple #7
0
        protected bool TrySendFrameInternal(ref Frame frame, TimeSpan timeout)
        {
            //  Process pending commands, if any.
            ProcessCommands(TimeSpan.Zero, true);

            //  Try to send the message.
            bool isFrameSent = m_protocol.TrySend(ref frame);

            if (isFrameSent)
                return true;

            //  In case of non-blocking send (Zero timeout) we'll simply return false
            if (timeout == TimeSpan.Zero)
                return false;

            if (timeout == Timeout.InfiniteTimeSpan)
            {
                while (true)
                {
                    ProcessCommands(timeout, false);

                    if (m_protocol.TrySend(ref frame))
                        return true;
                }
            }
            else
            {
                Stopwatch stopwatch = Stopwatch.StartNew();
                TimeSpan timeLeft = timeout;

                while (true)
                {
                    ProcessCommands(timeLeft, false);

                    if (m_protocol.TrySend(ref frame))
                        return true;

                    timeLeft = timeout - stopwatch.Elapsed;
                    if (timeLeft <= TimeSpan.Zero)
                        return false;
                }
            }
        }
Exemple #8
0
        protected bool TryReceiveFrameInternal(ref Frame frame, TimeSpan timeout)
        {
            //  Once every InboundPollRate messages check for signals and process
            //  incoming commands. This happens only if we are not polling altogether
            //  because there are messages available all the time. If poll occurs,
            //  ticks is set to zero and thus we avoid this code.
            //
            //  Note that 'TryReceiveFrame' uses different command throttling algorithm (the one
            //  described above) from the one used by 'TrySendFrame'. This is because counting
            //  ticks is more efficient than doing GetTimeSpan all the time.

            m_ticks++;
            if (m_ticks == InboundPollRate)
            {
                ProcessCommands(TimeSpan.Zero, false);
                m_ticks = 0;
            }

            //  Get the message.
            bool isFrameReceived = m_protocol.TryReceive(ref frame);

            //  If we have the message, return immediately.
            if (isFrameReceived)
                return true;

            //  If the message cannot be fetched immediately, there are two scenarios.
            //  For non-blocking recveive (zero timeout), commands are processed in case there's an
            //  activate reader command already waiting int a command pipe.
            //  If it's not, return false.
            if (timeout == TimeSpan.Zero)
            {
                ProcessCommands(TimeSpan.Zero, false);
                m_ticks = 0;

                return m_protocol.TryReceive(ref frame);
            }

            if (timeout == Timeout.InfiniteTimeSpan)
            {
                while (true)
                {
                    ProcessCommands(timeout, false);

                    if (m_protocol.TryReceive(ref frame))
                    {
                        m_ticks = 0;
                        return true;
                    }
                }
            }
            else
            {
                Stopwatch stopwatch = Stopwatch.StartNew();
                TimeSpan timeLeft = timeout;

                while (true)
                {
                    ProcessCommands(timeLeft, false);

                    if (m_protocol.TryReceive(ref frame))
                    {
                        m_ticks = 0;
                        return true;
                    }

                    timeLeft = timeout - stopwatch.Elapsed;
                    if (timeLeft <= TimeSpan.Zero)
                        return false;
                }
            }
        }
        /// <summary>
        /// Attempt to receive a single frame from <paramref cref="socket"/>, and decode as a string using <paramref name="encoding"/>.
        /// If no message is available within <paramref name="timeout"/>, return <c>false</c>.
        /// </summary>
        /// <param name="socket">The socket to receive from.</param>
        /// <param name="timeout">The maximum period of time to wait for a message to become available.</param>
        /// <param name="encoding">The encoding used to convert the frame's data to a string.</param>
        /// <param name="frameString">The content of the received message frame as a string, or <c>null</c> if no message was available.</param>
        /// <param name="more"><c>true</c> if another frame of the same message follows, otherwise <c>false</c>.</param>
        /// <returns><c>true</c> if a message was available, otherwise <c>false</c>.</returns>
        public static bool TryReceiveFrameString(this IReceive socket, TimeSpan timeout, Encoding encoding, out string frameString, out bool more)
        {
            var frame = new Frame();

            if (socket.TryReceiveFrame(ref frame, timeout))
            {
                more = frame.More;

                frameString = frame.Length > 0
                    ? encoding.GetString(frame.Data, 0, frame.Length)
                    : string.Empty;

                frame.Close();
                return true;
            }

            frameString = null;
            more = false;
            frame.Close();
            return false;
        }
        /// <summary>
        /// Attempt to receive a single frame from <paramref cref="socket"/>.  Reusing existing bytes-array if large enough.
        /// If no message is available within <paramref name="timeout"/>, return <c>false</c>.
        /// Indicate whether further frames exist via <paramref name="more"/>.
        /// </summary>
        /// <param name="socket">The socket to receive from.</param>
        /// <param name="timeout">The maximum period of time to wait for a message to become available.</param>
        /// <param name="bytes">The content of the received message frame. If pre-allocated and large enough the allocated array will be used. Otherwise new array will be allocated.</param>
        /// <param name="length">The length of the frame receieved.</param>        
        /// <param name="more"><c>true</c> if another frame of the same message follows, otherwise <c>false</c>.</param>               
        /// <returns><c>true</c> if a message was available, otherwise <c>false</c>.</returns>
        public static bool TryReceiveFrameBytes(this IReceive socket, TimeSpan timeout, ref byte[] bytes, out int length, out bool more)
        {
            var frame = new Frame();

            if (!socket.TryReceiveFrame(ref frame, timeout))
            {
                frame.Close();
                bytes = null;
                more = false;
                length = 0;
                return false;
            }

            if (bytes != null && bytes.Length >= frame.Length)
                frame.CopyDataTo(bytes);
            else
                bytes = frame.CloneData();

            length = frame.Length;
            more = frame.More;

            frame.Close();
            return true;
        }
 /// <summary>
 /// Block until the next message arrives, then make the message's data available via <paramref name="frame"/>.
 /// </summary>
 /// <remarks>
 /// The call  blocks until the next message arrives, and cannot be interrupted. This a convenient and safe when
 /// you know a message is available.
 /// </remarks>
 /// <param name="socket">The socket to receive from.</param>
 /// <param name="frame">An object to receive the frame's data into.</param>
 public static void ReceiveFrame(this IReceive socket, ref Frame frame)
 {
     var result = socket.TryReceiveFrame(ref frame, Timeout.InfiniteTimeSpan);
     Debug.Assert(result);
 }
        /// <summary>
        /// Attempt to receive a single frame from <paramref cref="socket"/>.
        /// If no message is available within <paramref name="timeout"/>, return <c>false</c>.
        /// Indicate whether further frames exist via <paramref name="more"/>.
        /// </summary>
        /// <param name="socket">The socket to receive from.</param>
        /// <param name="more"><c>true</c> if another frame of the same message follows, otherwise <c>false</c>.</param>
        /// <param name="timeout">The maximum period of time to wait for a message to become available.</param>
        /// <param name="bytes">The content of the received message frame, or <c>null</c> if no message was available.</param>
        /// <returns><c>true</c> if a message was available, otherwise <c>false</c>.</returns>
        public static bool TryReceiveFrameBytes(this IReceive socket, TimeSpan timeout, out byte[] bytes, out bool more)
        {
            var frame = new Frame();

            if (!socket.TryReceiveFrame(ref frame, timeout))
            {
                frame.Close();
                bytes = null;
                more = false;
                return false;
            }

            bytes = frame.CloneData();
            more = frame.More;

            frame.Close();
            return true;
        }
        /// <summary>
        /// Receive a single frame from <paramref cref="socket"/>, blocking until one arrives, and decode as a string using <paramref name="encoding"/>.
        /// Indicate whether further frames exist via <paramref name="more"/>.
        /// </summary>
        /// <param name="socket">The socket to receive from.</param>
        /// <param name="encoding">The encoding used to convert the frame's data to a string.</param>
        /// <param name="more"><c>true</c> if another frame of the same message follows, otherwise <c>false</c>.</param>
        /// <returns>The content of the received message frame as a string.</returns>        
        public static string ReceiveFrameString(this IReceive socket, Encoding encoding, out bool more)
        {
            var frame = new Frame();

            socket.ReceiveFrame(ref frame);

            more = frame.More;

            var str = frame.Length > 0
                ? encoding.GetString(frame.Data, 0, frame.Length)
                : string.Empty;

            frame.Close();
            return str;
        }
Exemple #14
0
 public bool TrySendFrame(ref Frame frame, TimeSpan timeout)
 {
     return base.TrySendFrameInternal(ref frame, timeout);
 }