Skip to main content

DealerSocket

Struct DealerSocket 

Source
pub struct DealerSocket<S = TcpStream>
where S: AsyncRead + AsyncWrite + Unpin,
{ /* private fields */ }
Expand description

A DEALER socket for asynchronous request-reply patterns.

DEALER sockets are fair-queuing clients that distribute messages across multiple server endpoints. They’re used for:

  • Load-balanced request-reply
  • Async RPC clients
  • Worker pools

§ZeroMQ Compatibility

Compatible with zmq::DEALER and zmq::ROUTER sockets from libzmq.

§Example

use monocoque::zmq::DealerSocket;
use bytes::Bytes;

// Connect to server
let mut socket = DealerSocket::connect("127.0.0.1:5555").await?;

// Send request
socket.send(vec![Bytes::from("REQUEST")]).await?;

// Receive reply
if let Ok(Some(reply)) = socket.recv().await {
    println!("Got reply: {:?}", reply);
}

Implementations§

Source§

impl DealerSocket

Source

pub async fn connect(endpoint: &str) -> Result<Self>

Connect to a ZeroMQ peer and create a DEALER socket.

Supports both TCP and IPC endpoints:

  • TCP: "tcp://127.0.0.1:5555" or "127.0.0.1:5555"
  • IPC: "ipc:///tmp/socket.sock" (Unix only)
§Arguments
  • endpoint - Endpoint to connect to
§Errors

Returns an error if:

  • The connection fails (network unreachable, connection refused, etc.)
  • DNS resolution fails for TCP endpoints
  • Invalid endpoint format
§Example
use monocoque::zmq::DealerSocket;

// TCP connection
let socket1 = DealerSocket::connect("tcp://127.0.0.1:5555").await?;

// IPC connection (Unix only)
#[cfg(unix)]
let socket2 = DealerSocket::connect("ipc:///tmp/socket.sock").await?;
Source

pub async fn connect_with_options( endpoint: &str, options: SocketOptions, ) -> Result<Self>

Connect to a ZeroMQ peer with custom socket options.

Stores the endpoint so the socket can reconnect automatically after failures.

§Example
use monocoque::zmq::{DealerSocket, SocketOptions};
use std::time::Duration;

let mut socket = DealerSocket::connect_with_options(
    "tcp://127.0.0.1:5555",
    SocketOptions::default().with_send_hwm(100),
).await?;
Source

pub async fn connect_ipc(path: &str) -> Result<DealerSocket<UnixStream>>

Connect to a ZeroMQ peer via IPC (Unix domain sockets).

Unix-only. Accepts IPC paths with or without ipc:// prefix.

§Example
use monocoque::zmq::DealerSocket;

let mut socket = DealerSocket::connect_ipc("/tmp/dealer.sock").await?;
Source

pub async fn bind(addr: impl ToSocketAddrs) -> Result<(TcpListener, Self)>

Bind to an address and accept the first connection.

This creates a server-side DEALER socket that accepts incoming connections. Useful for broker patterns where workers (REP sockets) connect to a DEALER backend.

§Returns

A tuple of (listener, socket) where:

  • listener can be used to accept additional connections
  • socket is ready to send/receive with the first peer
§Errors

Returns an error if:

  • The address is already in use
  • Permission denied (e.g., binding to privileged port without root)
  • Invalid address format
§Example
use monocoque::zmq::DealerSocket;

// Bind DEALER backend for worker connections
let (listener, socket) = DealerSocket::bind("127.0.0.1:5556").await?;

// Use socket for first connection
// Accept more connections from listener if needed:
// let (stream, _) = listener.accept().await?;
// let socket2 = DealerSocket::from_tcp(stream).await?;
Source

pub async fn from_tcp(stream: TcpStream) -> Result<Self>

Create a DEALER socket from a TCP stream with TCP_NODELAY enabled.

This method automatically enables TCP_NODELAY for optimal performance, preventing Nagle’s algorithm from buffering small packets.

Uses default buffer sizes (8KB) and socket options. For custom configuration, use with_options().

§Example
use monocoque::zmq::DealerSocket;
use monocoque_core::rt::TcpStream;

let stream = TcpStream::connect("127.0.0.1:5555").await?;
let socket = DealerSocket::from_tcp(stream).await?;
Source

pub async fn from_tcp_with_options( stream: TcpStream, options: SocketOptions, ) -> Result<Self>

Create a DEALER socket from a TCP stream with custom options.

Provides full control over buffer sizes, HWM, timeouts, etc. through SocketOptions.

§Examples
use monocoque::zmq::{DealerSocket, SocketOptions};
use monocoque_core::rt::TcpStream;

let stream = TcpStream::connect("127.0.0.1:5555").await?;

// Customize HWM only (uses default 8KB buffers)
let socket = DealerSocket::from_tcp_with_options(
    stream,
    SocketOptions::default().with_send_hwm(100)
).await?;
// Customize both buffers and HWM
let socket = DealerSocket::from_tcp_with_options(
    stream,
    SocketOptions::default()
        .with_buffer_sizes(4096, 4096)  // 4KB buffers for low latency
        .with_send_hwm(100)
).await?;
Source

pub async fn with_options<Stream>( stream: Stream, options: SocketOptions, ) -> Result<DealerSocket<Stream>>
where Stream: AsyncRead + AsyncWrite + Unpin,

Create a DEALER socket from any stream with custom options.

This is the most flexible constructor - works with TCP, Unix, or in-memory streams. Useful for testing with duplex streams.

§Example
use monocoque::zmq::{DealerSocket, SocketOptions};
use monocoque_core::rt::TcpStream;

let stream = TcpStream::connect("127.0.0.1:5555").await?;
let socket = DealerSocket::with_options(
    stream,
    SocketOptions::default().with_send_hwm(10)
).await?;
Source§

impl<S> DealerSocket<S>
where S: AsyncRead + AsyncWrite + Unpin,

Source

pub fn monitor(&mut self) -> SocketMonitor

Enable monitoring for this socket.

Returns a receiver for socket lifecycle events. Once enabled, the socket will emit events like Connected, Disconnected, etc.

§Example
use monocoque::zmq::{DealerSocket, SocketEvent};

let mut socket = DealerSocket::connect("127.0.0.1:5555").await?;
let monitor = socket.monitor();

// Spawn task to handle events
monocoque::rt::spawn_detached(async move {
    while let Ok(event) = monitor.recv_async().await {
        println!("Socket event: {}", event);
    }
});
Source

pub async fn send(&mut self, msg: Vec<Bytes>) -> Result<()>

Send a multipart message.

Messages are sent asynchronously - this returns immediately after queuing the message for transmission.

§Errors

Returns an error if the underlying connection is closed or broken.

§Example
socket.send(vec![
    Bytes::from("part1"),
    Bytes::from("part2"),
]).await?;
Source

pub fn send_buffered(&mut self, msg: Vec<Bytes>) -> Result<()>

Send a message to the internal buffer without flushing.

Use this for batching multiple messages before a single flush. Call flush() to send all buffered messages.

§Example
// Batch 100 messages
for i in 0..100 {
    socket.send_buffered(vec![Bytes::from(format!("msg {}", i))])?;
}
// Single I/O operation for all 100 messages
socket.flush().await?;
Source

pub async fn flush(&mut self) -> Result<()>

Flush all buffered messages to the network.

Sends all messages buffered by send_buffered() in a single I/O operation.

Source

pub async fn send_batch(&mut self, messages: &[Vec<Bytes>]) -> Result<()>

Send multiple messages in a single batch (convenience method).

This is equivalent to calling send_buffered() for each message followed by flush(), but more ergonomic.

§Example
let messages = vec![
    vec![Bytes::from("msg1")],
    vec![Bytes::from("msg2")],
    vec![Bytes::from("msg3")],
];
socket.send_batch(&messages).await?;
Source

pub fn buffered_bytes(&self) -> usize

Get the number of bytes currently buffered.

Source

pub fn events(&self) -> u32

Get the socket type.

§ZeroMQ Compatibility

Get current socket events (read/write readiness).

Returns a bitmask:

  • 1 (POLLIN): Can receive without blocking
  • 2 (POLLOUT): Can send without blocking
§ZeroMQ Compatibility

Corresponds to ZMQ_EVENTS (15) option.

Source

pub async fn recv(&mut self) -> Result<Option<Vec<Bytes>>>

Receive a multipart message.

Returns None if the connection is closed.

§Example
while let Ok(Some(msg)) = socket.recv().await {
    println!("Received {} parts", msg.len());
}
Source§

impl<S> DealerSocket<S>
where S: AsyncRead + AsyncWrite + Unpin,

Source

pub const fn socket_type(&self) -> SocketType

Get the socket type.

Always returns SocketType::Dealer for DEALER sockets.

§ZeroMQ Compatibility

Corresponds to ZMQ_TYPE (16) socket option.

Source

pub fn last_endpoint(&self) -> Option<&str>

Get the last connected endpoint as a string.

Returns the endpoint this socket connected to, if any.

§ZeroMQ Compatibility

Corresponds to ZMQ_LAST_ENDPOINT (32) socket option.

Source

pub fn has_more(&self) -> bool

Check if more message frames are expected.

For multipart messages, this indicates if more frames follow.

§ZeroMQ Compatibility

Corresponds to ZMQ_RCVMORE (13) socket option.

Source

pub fn options_mut(&mut self) -> &mut SocketOptions

Get mutable access to socket options.

Allows runtime modification of socket behavior.

Source

pub const fn options(&self) -> &SocketOptions

Get immutable access to socket options.

Source§

impl DealerSocket<UnixStream>

Source

pub async fn from_unix_stream(stream: UnixStream) -> Result<Self>

Create a DEALER socket from an existing Unix domain socket stream (IPC).

Source

pub async fn from_unix_stream_with_options( stream: UnixStream, options: SocketOptions, ) -> Result<Self>

Create a DEALER socket from an existing Unix stream with custom options.

Trait Implementations§

Source§

impl ProxySocket for DealerSocket<TcpStream>

Source§

fn recv_multipart<'life0, 'async_trait>( &'life0 mut self, ) -> Pin<Box<dyn Future<Output = Result<Option<Vec<Bytes>>>> + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Receive a multipart message from the socket. Read more
Source§

fn send_multipart<'life0, 'async_trait>( &'life0 mut self, msg: Vec<Bytes>, ) -> Pin<Box<dyn Future<Output = Result<()>> + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Send a multipart message to the socket. Read more
Source§

fn socket_desc(&self) -> &'static str

Get a description of the socket for logging.

Auto Trait Implementations§

§

impl<S = TcpStream> !Freeze for DealerSocket<S>

§

impl<S> RefUnwindSafe for DealerSocket<S>
where S: RefUnwindSafe,

§

impl<S> Send for DealerSocket<S>
where S: Send,

§

impl<S> Sync for DealerSocket<S>
where S: Sync,

§

impl<S> Unpin for DealerSocket<S>

§

impl<S> UnsafeUnpin for DealerSocket<S>
where S: UnsafeUnpin,

§

impl<S> UnwindSafe for DealerSocket<S>
where S: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more