123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773 |
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using NetMQ.Utils;
- namespace NetMQ
- {
- /// <summary>
- /// This static class serves to provide extension methods for IOutgoingSocket.
- /// </summary>
- public static class OutgoingSocketExtensions
- {
- /// <summary>
- /// Block until the message can be sent.
- /// </summary>
- /// <remarks>
- /// The call blocks until the message can be sent and cannot be interrupted.
- /// Whether the message can be sent depends on the socket type.
- /// </remarks>
- /// <param name="socket">The socket to send the message on.</param>
- /// <param name="msg">An object with message's data to send.</param>
- /// <param name="more">Indicate if another frame is expected after this frame</param>
- public static void Send(this IOutgoingSocket socket, ref Msg msg, bool more)
- {
- var result = socket.TrySend(ref msg, SendReceiveConstants.InfiniteTimeout, more);
- Debug.Assert(result);
- }
- #region Sending Byte Array
- #region Blocking
- /// <summary>
- /// Transmit a byte-array of data over this socket, block until frame is sent.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="data">the byte-array of data 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 IOutgoingSocket socket, byte[] data, bool more = false)
- {
- SendFrame(socket, data, data.Length, more);
- }
- /// <summary>
- /// Transmit a byte-array of data over this socket, block until frame is sent.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket 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 IOutgoingSocket socket, byte[] data, int length, bool more = false)
- {
- var msg = new Msg();
- msg.InitPool(length);
- data.Slice(0, length).CopyTo(msg);
- socket.Send(ref msg, more);
- msg.Close();
- }
- /// <summary>
- /// Transmit a byte-array of data over this socket, block until frame is sent.
- /// Send more frame, another frame must be sent after this frame. Use to chain Send methods.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="data">the byte-array of data to send</param>
- /// <returns>a reference to this IOutgoingSocket so that method-calls may be chained together</returns>
- public static IOutgoingSocket SendMoreFrame(this IOutgoingSocket socket, byte[] data)
- {
- SendFrame(socket, data, true);
- return socket;
- }
- /// <summary>
- /// Transmit a byte-array of data over this socket, block until frame is sent.
- /// Send more frame, another frame must be sent after this frame. Use to chain Send methods.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket 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>
- /// <returns>a reference to this IOutgoingSocket so that method-calls may be chained together</returns>
- public static IOutgoingSocket SendMoreFrame(this IOutgoingSocket socket, byte[] data, int length)
- {
- SendFrame(socket, data, length, true);
- return socket;
- }
- #endregion
- #region Timeout
- /// <summary>
- /// Attempt to transmit a single frame on <paramref name="socket"/>.
- /// If message cannot be sent within <paramref name="timeout"/>, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket 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 IOutgoingSocket socket, TimeSpan timeout, byte[] data, int length, bool more = false)
- {
- var msg = new Msg();
- msg.InitPool(length);
- data.Slice(0, length).CopyTo(msg);
- if (!socket.TrySend(ref msg, timeout, more))
- {
- msg.Close();
- return false;
- }
- msg.Close();
- return true;
- }
- /// <summary>
- /// Attempt to transmit a single frame on <paramref name="socket"/>.
- /// If message cannot be sent within <paramref name="timeout"/>, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket 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="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 IOutgoingSocket socket, TimeSpan timeout, byte[] data, bool more = false)
- {
- return TrySendFrame(socket, timeout, data, data.Length, more);
- }
- #endregion
- #region Immediate
- /// <summary>
- /// Attempt to transmit a single frame on <paramref name="socket"/>.
- /// If message cannot be sent immediately, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="data">the byte-array of data 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>
- /// <returns><c>true</c> if a message was available, otherwise <c>false</c>.</returns>
- public static bool TrySendFrame(this IOutgoingSocket socket, byte[] data,
- bool more = false)
- {
- return TrySendFrame(socket, TimeSpan.Zero, data, more);
- }
- /// <summary>
- /// Attempt to transmit a single frame on <paramref name="socket"/>.
- /// If message cannot be sent immediately, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket 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>
- /// <returns><c>true</c> if a message was available, otherwise <c>false</c>.</returns>
- public static bool TrySendFrame(this IOutgoingSocket socket, byte[] data, int length,
- bool more = false)
- {
- return TrySendFrame(socket, TimeSpan.Zero, data, length, more);
- }
- #endregion
- #endregion
- #region Sending a multipart message as byte arrays
- #region Blocking
- /// <summary>
- /// Send multiple frames on <paramref name="socket"/>, blocking until all frames are sent.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="frames">frames to transmit</param>
- public static void SendMultipartBytes(this IOutgoingSocket socket, params byte[][] frames)
- {
- SendMultipartBytes(socket, (IEnumerable<byte[]>)frames);
- }
- /// <summary>
- /// Send multiple frames on <paramref name="socket"/>, blocking until all frames are sent.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="frames">frames to transmit</param>
- public static void SendMultipartBytes(this IOutgoingSocket socket, IEnumerable<byte[]> frames)
- {
- var enumerator = frames.GetEnumerator();
- try
- {
- // move to the first element, if false frames is empty
- if (!enumerator.MoveNext())
- {
- throw new ArgumentException("frames is empty", nameof(frames));
- }
- var current = enumerator.Current;
- // we always one item back to make sure we send the last frame without the more flag
- while (enumerator.MoveNext())
- {
- // this is a more frame
- socket.SendMoreFrame(current);
- current = enumerator.Current;
- }
- // sending the last frame
- socket.SendFrame(current);
- }
- finally
- {
- enumerator.Dispose();
- }
- }
- #endregion
- #region Timeout
- /// <summary>
- /// Attempt to transmit a multiple frames on <paramref name="socket"/>.
- /// If frames cannot be sent within <paramref name="timeout"/>, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="timeout">The maximum period of time to try to send a message.</param>
- /// <param name="frames">frames to transmit</param>
- public static bool TrySendMultipartBytes(this IOutgoingSocket socket, TimeSpan timeout, params byte[][] frames)
- {
- return TrySendMultipartBytes(socket, timeout, (IEnumerable<byte[]>)frames);
- }
- /// <summary>
- /// Attempt to transmit a multiple frames on <paramref name="socket"/>.
- /// If frames cannot be sent within <paramref name="timeout"/>, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="timeout">The maximum period of time to try to send a message.</param>
- /// <param name="frames">frames to transmit</param>
- public static bool TrySendMultipartBytes(this IOutgoingSocket socket, TimeSpan timeout,
- IEnumerable<byte[]> frames)
- {
- var enumerator = frames.GetEnumerator();
- try
- {
- // move to the first element, if false frames is empty
- if (!enumerator.MoveNext())
- {
- throw new ArgumentException("frames is empty", nameof(frames));
- }
- var current = enumerator.Current;
- // only the first frame need to be sent with a timeout
- if (!enumerator.MoveNext())
- {
- return socket.TrySendFrame(timeout, current);
- }
- else
- {
- bool sentSuccessfully = socket.TrySendFrame(timeout, current, true);
- if (!sentSuccessfully)
- return false;
- }
- // fetching the second frame
- current = enumerator.Current;
- // we always one item back to make sure we send the last frame without the more flag
- while (enumerator.MoveNext())
- {
- // this is a more frame
- socket.SendMoreFrame(current);
- current = enumerator.Current;
- }
- // sending the last frame
- socket.SendFrame(current);
- return true;
- }
- finally
- {
- enumerator.Dispose();
- }
- }
- #endregion
- #region Immediate
- /// <summary>
- /// Attempt to transmit a multiple frames on <paramref name="socket"/>.
- /// If frames cannot be sent immediately, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="frames">frames to transmit</param>
- public static bool TrySendMultipartBytes(this IOutgoingSocket socket, params byte[][] frames)
- {
- return TrySendMultipartBytes(socket, TimeSpan.Zero, (IEnumerable<byte[]>)frames);
- }
- /// <summary>
- /// Attempt to transmit a multiple frames on <paramref name="socket"/>.
- /// If frames cannot be sent immediately, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="frames">frames to transmit</param>
- public static bool TrySendMultipartBytes(this IOutgoingSocket socket, IEnumerable<byte[]> frames)
- {
- return TrySendMultipartBytes(socket, TimeSpan.Zero, frames);
- }
- #endregion
- #endregion
- #region Sending Strings
- #region Blocking
- /// <summary>
- /// Transmit a string over this socket, block until frame is sent.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket 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 IOutgoingSocket socket, string message, bool more = false)
- {
- var msg = new Msg();
- // 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.
- msg.InitPool(SendReceiveConstants.DefaultEncoding.GetByteCount(message));
- // Encode the string into the buffer
- SendReceiveConstants.DefaultEncoding.GetBytes(message, msg);
- socket.Send(ref msg, more);
- msg.Close();
- }
- /// <summary>
- /// Transmit a string over this socket, block until frame is sent.
- /// Send more frame, another frame must be sent after this frame. Use to chain Send methods.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="message">the string to send</param>
- /// <returns>a reference to this IOutgoingSocket so that method-calls may be chained together</returns>
- public static IOutgoingSocket SendMoreFrame(this IOutgoingSocket socket, string message)
- {
- SendFrame(socket, message, true);
- return socket;
- }
- #endregion
- #region Timeout
- /// <summary>
- /// Attempt to transmit a single string frame on <paramref name="socket"/>.
- /// If message cannot be sent within <paramref name="timeout"/>, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="timeout">The maximum period of time to try to send a message.</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>
- /// <returns><c>true</c> if a message was available, otherwise <c>false</c>.</returns>
- public static bool TrySendFrame(this IOutgoingSocket socket, TimeSpan timeout, string message, bool more = false)
- {
- var msg = new Msg();
- // 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.
- msg.InitPool(SendReceiveConstants.DefaultEncoding.GetByteCount(message));
- // Encode the string into the buffer
- SendReceiveConstants.DefaultEncoding.GetBytes(message, msg);
- if (!socket.TrySend(ref msg, timeout, more))
- {
- msg.Close();
- return false;
- }
- msg.Close();
- return true;
- }
- #endregion
- #region Immediate
- /// <summary>
- /// Attempt to transmit a single string frame on <paramref name="socket"/>.
- /// If message cannot be sent immediately, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket 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>
- /// <returns><c>true</c> if a message was available, otherwise <c>false</c>.</returns>
- public static bool TrySendFrame(this IOutgoingSocket socket, string message, bool more = false)
- {
- return TrySendFrame(socket, TimeSpan.Zero, message, more);
- }
- #endregion
- #endregion
- #region Sending a multipart message as NetMQMessage
- #region Blocking
- /// <summary>
- /// Send the multiple part message on the <paramref name="socket"/>, blocking until the entire message is sent.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="message">message to transmit</param>
- public static void SendMultipartMessage(this IOutgoingSocket socket, NetMQMessage message)
- {
- if (message.FrameCount == 0)
- throw new ArgumentException("message is empty", nameof(message));
- for (int i = 0; i < message.FrameCount - 1; i++)
- {
- socket.SendMoreFrame(message[i].Buffer, message[i].MessageSize);
- }
- socket.SendFrame(message.Last.Buffer, message.Last.MessageSize);
- }
- #endregion
- #region Timeout
- /// <summary>
- /// Attempt to transmit a multiple message on <paramref name="socket"/>.
- /// If message cannot be sent within <paramref name="timeout"/>, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="timeout">The maximum period of time to try to send a message.</param>
- /// <param name="message">message to transmit</param>
- public static bool TrySendMultipartMessage(this IOutgoingSocket socket, TimeSpan timeout, NetMQMessage message)
- {
- if (message.FrameCount == 0)
- throw new ArgumentException("message is empty", nameof(message));
- else if (message.FrameCount == 1)
- {
- return TrySendFrame(socket, timeout, message[0].Buffer, message[0].MessageSize);
- }
- else
- {
- bool sentSuccessfully = TrySendFrame(socket, timeout, message[0].Buffer, message[0].MessageSize, true);
- if (!sentSuccessfully)
- return false;
- }
- for (int i = 1; i < message.FrameCount - 1; i++)
- {
- socket.SendMoreFrame(message[i].Buffer, message[i].MessageSize);
- }
- socket.SendFrame(message.Last.Buffer, message.Last.MessageSize);
- return true;
- }
- #endregion
- #region Immediate
- /// <summary>
- /// Attempt to transmit a multiple message on <paramref name="socket"/>.
- /// If frames cannot be sent immediately, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="message">message to transmit</param>
- public static bool TrySendMultipartMessage(this IOutgoingSocket socket, NetMQMessage message)
- {
- return TrySendMultipartMessage(socket, TimeSpan.Zero, message);
- }
- #endregion
- #endregion
- #region Sending an empty frame
- #region Blocking
- /// <summary>
- /// Transmit an empty frame over this socket, block until frame is sent.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</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 SendFrameEmpty(this IOutgoingSocket socket, bool more = false)
- {
- SendFrame(socket, EmptyArray<byte>.Instance, more);
- }
- /// <summary>
- /// Transmit an empty frame over this socket, block until frame is sent.
- /// Send more frame, another frame must be sent after this frame. Use to chain Send methods.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <returns>a reference to this IOutgoingSocket so that method-calls may be chained together</returns>
- public static IOutgoingSocket SendMoreFrameEmpty(this IOutgoingSocket socket)
- {
- SendFrame(socket, EmptyArray<byte>.Instance, true);
- return socket;
- }
- #endregion
- #region Timeout
- /// <summary>
- /// Attempt to transmit an empty frame on <paramref name="socket"/>.
- /// If message cannot be sent within <paramref name="timeout"/>, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="timeout">The maximum period of time to try to send a message.</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 TrySendFrameEmpty(this IOutgoingSocket socket, TimeSpan timeout, bool more = false)
- {
- return TrySendFrame(socket, timeout, EmptyArray<byte>.Instance, more);
- }
- #endregion
- #region Immediate
- /// <summary>
- /// Attempt to transmit an empty frame on <paramref name="socket"/>.
- /// If message cannot be sent immediately, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</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 TrySendFrameEmpty(this IOutgoingSocket socket, bool more = false)
- {
- return TrySendFrame(socket, EmptyArray<byte>.Instance, more);
- }
- #endregion
- #endregion
- #region Sending Signals
- /// <summary>
- /// Transmit a status-signal over this socket.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="status">a byte that contains the status signal to send</param>
- private static void Signal(this IOutgoingSocket socket, byte status)
- {
- long signalValue = 0x7766554433221100L + status;
- Msg msg = new Msg();
- msg.InitPool(8);
- NetworkOrderBitsConverter.PutInt64(signalValue, msg);
- socket.Send(ref msg, false);
- msg.Close();
- }
- /// <summary>
- /// Attempt to transmit a status-signal over this socket.
- /// If signal cannot be sent immediately, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="status">a byte that contains the status signal to send</param>
- private static bool TrySignal(this IOutgoingSocket socket, byte status)
- {
- long signalValue = 0x7766554433221100L + status;
- Msg msg = new Msg();
- msg.InitPool(8);
- NetworkOrderBitsConverter.PutInt64(signalValue, msg);
- if (!socket.TrySend(ref msg, TimeSpan.Zero, false))
- {
- msg.Close();
- return false;
- }
- msg.Close();
- return true;
- }
- /// <summary>
- /// Transmit a specific status-signal over this socket that indicates OK.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- public static void SignalOK(this IOutgoingSocket socket)
- {
- socket.Signal(0);
- }
- /// <summary>
- /// Attempt to transmit a specific status-signal over this socket that indicates OK.
- /// If signal cannot be sent immediately, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- public static bool TrySignalOK(this IOutgoingSocket socket)
- {
- return TrySignal(socket, 0);
- }
- /// <summary>
- /// Transmit a specific status-signal over this socket that indicates there is an error.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- public static void SignalError(this IOutgoingSocket socket)
- {
- socket.Signal(1);
- }
- /// <summary>
- /// Attempt to transmit a specific status-signal over this socket that indicates there is an error.
- /// If signal cannot be sent immediately, return <c>false</c>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- public static bool TrySignalError(this IOutgoingSocket socket)
- {
- return socket.TrySignal(1);
- }
- #endregion
- #region Sending Routing Key
- /// <summary>
- /// Send routing key over <paramref name="socket"/>.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="routingKey">the routing key to send</param>
- public static void SendMoreFrame(this IOutgoingSocket socket, RoutingKey routingKey)
- {
- socket.SendMoreFrame(routingKey.Bytes);
- }
- /// <summary>
- /// Attempt to transmit routing key over <paramref name="socket"/>.
- /// If message cannot be sent immediately, return <c>false</c>.
- /// Routing is always sent as more frame.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="routingKey">the routing key to send</param>
- /// <returns><c>true</c> if a message was available, otherwise <c>false</c>.</returns>
- public static bool TrySendFrame(this IOutgoingSocket socket, RoutingKey routingKey)
- {
- return socket.TrySendFrame(routingKey.Bytes, true);
- }
- /// <summary>
- /// Attempt to transmit routing key over <paramref name="socket"/>.
- /// If message cannot be sent within <paramref name="timeout"/>, return <c>false</c>.
- /// Routing is always sent as more frame.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="timeout">The maximum period of time to try to send a message.</param>
- /// <param name="routingKey">the routing key to send</param>
- /// <returns><c>true</c> if a message was available, otherwise <c>false</c>.</returns>
- public static bool TrySendFrame(this IOutgoingSocket socket, TimeSpan timeout, RoutingKey routingKey)
- {
- return socket.TrySendFrame(timeout, routingKey.Bytes, true);
- }
- #endregion
- #region Sending Routing Keys
- /// <summary>
- /// Send empty list of routing keys over <paramref name="socket"/>, append an empty message at the end of the keys.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- public static IOutgoingSocket SendEmptyRoutingKeys(this IOutgoingSocket socket)
- {
- return socket.SendMoreFrameEmpty();
- }
- /// <summary>
- /// Send a single routing key over <paramref name="socket"/>, append an empty message afterwards.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="routingKeys">the routing keys to send</param>
- public static IOutgoingSocket SendRoutingKeys(this IOutgoingSocket socket, params RoutingKey[] routingKeys)
- {
- foreach(var routingKey in routingKeys)
- socket.SendMoreFrame(routingKey);
- socket.SendMoreFrameEmpty();
- return socket;
- }
- /// <summary>
- /// Send routing keys over <paramref name="socket"/>, append an empty message at the end of the keys.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="routingKeys">the routing keys to send</param>
- public static IOutgoingSocket SendRoutingKeys(this IOutgoingSocket socket, IEnumerable<RoutingKey> routingKeys)
- {
- foreach(var routingKey in routingKeys)
- socket.SendMoreFrame(routingKey);
- socket.SendMoreFrameEmpty();
- return socket;
- }
- /// <summary>
- /// Attempt to transmit routing keys over <paramref name="socket"/>.
- /// If message cannot be sent immediately, return <c>false</c>.
- /// Routing is always sent as more frame.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="routingKeys">the routing keys to send</param>
- /// <returns><c>true</c> if a message was available, otherwise <c>false</c>.</returns>
- public static bool TrySendRoutingKeys(this IOutgoingSocket socket, IEnumerable<RoutingKey> routingKeys)
- {
- return socket.TrySendRoutingKeys(TimeSpan.Zero, routingKeys);
- }
- /// <summary>
- /// Attempt to transmit routing key over <paramref name="socket"/>.
- /// If message cannot be sent within <paramref name="timeout"/>, return <c>false</c>.
- /// Routing is always sent as more frame.
- /// </summary>
- /// <param name="socket">the IOutgoingSocket to transmit on</param>
- /// <param name="timeout">The maximum period of time to try to send a message.</param>
- /// <param name="routingKeys">the routing keys to send</param>
- /// <returns><c>true</c> if a message was available, otherwise <c>false</c>.</returns>
- public static bool TrySendRoutingKeys(this IOutgoingSocket socket, TimeSpan timeout, IEnumerable<RoutingKey> routingKeys)
- {
- var enumerator = routingKeys.GetEnumerator();
-
- // Empty collection, just trying to send the empty message
- if (!enumerator.MoveNext())
- return socket.TrySendFrameEmpty(timeout, true);
- if (!socket.TrySendFrame(enumerator.Current))
- return false;
- while (enumerator.MoveNext())
- socket.SendMoreFrame(enumerator.Current);
- socket.SendMoreFrameEmpty();
- return true;
- }
- #endregion
- }
- }
|