Maintainers
Pricing
Enterprise
More
More
Documentation
Try Live
Rankings
Install
Blog
Docs7
Ask
New
Add Docs
NetMQ
https://github.com/zeromq/netmq
Admin
A 100% native C# implementation of ZeroMQ for .NET
Tokens:
14,293
Snippets:
73
Trust Score:
7.6
Update:
1 year ago
Context
Chat
Benchmark
72.38
Latest
Show doc for...
Code
Info
Show Results
Tokens:
Raw
Copy
Link
Tokens:
Raw
Copy
Link
### Batch File for Running NetMQ Example with One Worker (Shell) Source: https://github.com/zeromq/netmq/blob/master/docs/push-pull.md This batch file orchestrates the execution of the NetMQ example components: Ventilator, Sink, and a single Worker. It navigates to the respective build directories and starts each executable. This script is useful for testing the distributed messaging pattern with a minimal setup. ```text cd Ventilator/bin/Debug start Ventilator.exe cd../../.. cd Sink/bin/Debug start Sink.exe cd../../.. cd Worker/bin/Debug start Worker.exe ``` -------------------------------- ### Run NetMQ Load Balancing Example (Batch) Source: https://github.com/zeromq/netmq/blob/master/docs/push-pull.md This batch script executes the NetMQ load balancing example. It starts the Ventilator, Sink, and four Worker processes in sequence. Ensure that the compiled executables are in their respective Debug directories relative to the script's location. ```batch cd Ventilator/bin/Debug start Ventilator.exe cd../../.. cd Sink/bin/Debug start Sink.exe cd../../.. cd Worker/bin/Debug start Worker.exe start Worker.exe start Worker.exe start Worker.exe ``` -------------------------------- ### NetMQ Basic Request-Response Example (C#) Source: https://github.com/zeromq/netmq/blob/master/README.md Demonstrates a simple request-response pattern using NetMQ sockets in C#. It shows how to create server and client sockets, send messages, and receive responses. Ensure NetMQ is installed via NuGet. ```csharp using NetMQ; using NetMQ.Sockets; public class NetMQExample { public static void Main(string[] args) { using (var server = new ResponseSocket("@tcp://localhost:5556")) // bind using (var client = new RequestSocket(">tcp://localhost:5556")) // connect { // Send a message from the client socket client.SendFrame("Hello"); // Receive the message from the server socket string m1 = server.ReceiveFrameString(); Console.WriteLine("From Client: {0}", m1); // Send a response back from the server server.SendFrame("Hi Back"); // Receive the response from the client socket string m2 = client.ReceiveFrameString(); Console.WriteLine("From Server: {0}", m2); } } } ``` -------------------------------- ### Batch File for Running NetMQ Example with Two Workers (Shell) Source: https://github.com/zeromq/netmq/blob/master/docs/push-pull.md This batch file sets up and runs the NetMQ example with two Worker instances concurrently. It starts the Ventilator, Sink, and then launches two separate Worker processes. This configuration allows for testing the scalability and load distribution capabilities of the NetMQ messaging system. ```text cd Ventilator/bin/Debug start Ventilator.exe cd../../.. cd Sink/bin/Debug start Sink.exe cd../../.. cd Worker/bin/Debug start Worker.exe start Worker.exe ``` -------------------------------- ### Batch Script for Running Publisher and Subscribers Source: https://github.com/zeromq/netmq/blob/master/docs/pub-sub.md These batch scripts provide a simple way to launch the publisher and multiple subscriber instances for testing the NetMQ Pub/Sub pattern. They automate the process of starting the publisher and then launching subscribers for different topics. ```batch @echo off start "Publisher" RunPublisher.bat start "Subscriber TopicA" RunSubscriber.bat TopicA start "Subscriber TopicB" RunSubscriber.bat TopicB start "Subscriber All" RunSubscriber.bat All ``` ```batch @echo off cd Publisher\bin\Debug Publisher.exe ``` ```batch @echo off set "topic=%~1" cd Subscriber\bin\Debug Subscriber.exe %topic% ``` -------------------------------- ### NetMQ Request-Response Example in C# Source: https://github.com/zeromq/netmq/blob/master/docs/message.md A basic example demonstrating a request-response pattern using NetMQ ResponseSocket and RequestSocket in C#. It shows sending and receiving string messages between a server and a client. ```csharp using (var server = new ResponseSocket("@tcp://127.0.0.1:5556")) using (var client = new RequestSocket (">tcp://127.0.0.1:5556")) { client.Send("Hello"); string fromClientMessage = server.ReceiveFrameString(); Console.WriteLine("From Client: {0}", fromClientMessage); server.SendFrame("Hi Back"); string fromServerMessage = client.ReceiveFrameString(); Console.WriteLine("From Server: {0}", fromServerMessage); Console.ReadLine(); } ``` -------------------------------- ### C#: Full NetMQ Example: Sending and Receiving Source: https://github.com/zeromq/netmq/blob/master/docs/message.md A comprehensive example illustrating both sending multi-frame messages (using SendMoreFrame and SendFrame) and receiving them (using ReceiveFrameString in a loop and ReceiveMultipartMessage) with NetMQ sockets. This demonstrates a complete client-server interaction. ```csharp using (var server = new ResponseSocket("@tcp://127.0.0.1:5556")) using (var client = new RequestSocket(">tcp://127.0.0.1:5556")) { // client sends message consisting of two frames Console.WriteLine("Client sending"); client.SendMoreFrame("A").SendFrame("Hello"); // server receives frames bool more = true; while (more) { string frame = server.ReceiveFrameString(out more); Console.WriteLine("Server received frame={0} more={1}", frame, more); } Console.WriteLine("================================"); // server sends message, this time using NetMqMessage var msg = new NetMQMessage(); msg.Append("From"); msg.Append("Server"); Console.WriteLine("Server sending"); server.SendMultipartMessage(msg); // client receives the message msg = client.ReceiveMultipartMessage(); Console.WriteLine("Client received {0} frames", msg.FrameCount); foreach (var frame in msg) Console.WriteLine("Frame={0}", frame.ConvertToString()); Console.ReadLine(); } ``` -------------------------------- ### NetMQ Request/Response Example Source: https://github.com/zeromq/netmq/blob/master/docs/request-response.md Demonstrates the basic Request/Response pattern using NetMQ's RequestSocket and ResponseSocket within the same process. It shows a simple exchange of messages: sending 'Hello' from the requestor and receiving 'World' as a response. ```csharp using (var responseSocket = new ResponseSocket("@tcp://*:5555")) using (var requestSocket = new RequestSocket(">tcp://localhost:5555")) { Console.WriteLine("requestSocket : Sending 'Hello'"); requestSocket.SendFrame("Hello"); var message = responseSocket.ReceiveFrameString(); Console.WriteLine("responseSocket : Server Received '{0}'", message); Console.WriteLine("responseSocket Sending 'World'"); responseSocket.SendFrame("World"); message = requestSocket.ReceiveFrameString(); Console.WriteLine("requestSocket : Received '{0}'", message); Console.ReadLine(); } ``` -------------------------------- ### NetMQ Pub/Sub Example: Publisher in C# Source: https://github.com/zeromq/netmq/blob/master/docs/pub-sub.md A complete C# example of a NetMQ publisher that randomly sends messages on either 'TopicA' or 'TopicB' every 500 milliseconds. It demonstrates binding the socket to a specific address and sending multipart messages with topics. The SendHighWatermark option is configured to manage message queueing. ```csharp using System; using System.Threading; using NetMQ; using NetMQ.Sockets; namespace Publisher { class Program { static void Main(string[] args) { Random rand = new Random(50); using (var pubSocket = new PublisherSocket()) { Console.WriteLine("Publisher socket binding..."); pubSocket.Options.SendHighWatermark = 1000; pubSocket.Bind("tcp://*:12345"); for (var i = 0; i < 100; i++) { var randomizedTopic = rand.NextDouble(); if (randomizedTopic > 0.5) { var msg = "TopicA msg-" + i; Console.WriteLine("Sending message : {0}", msg); pubSocket.SendMoreFrame("TopicA").SendFrame(msg); } else { var msg = "TopicB msg-" + i; Console.WriteLine("Sending message : {0}", msg); pubSocket.SendMoreFrame("TopicB").SendFrame(msg); } Thread.Sleep(500); } } } } } ``` -------------------------------- ### NetMQ Intermediary Proxy Example (C#) Source: https://github.com/zeromq/netmq/blob/master/docs/xpub-xsub.md This C# code shows how to set up an intermediary using NetMQ's Proxy class. It binds an XPublisherSocket and an XSubscriberSocket to different addresses and uses the Proxy to relay messages bidirectionally between them, facilitating the XPub/XSub pattern. ```csharp using (var xpubSocket = new XPublisherSocket()) using (var xsubSocket = new XSubscriberSocket()) { xpubSocket.Bind("tcp://127.0.0.1:1234"); xsubSocket.Bind("tcp://127.0.0.1:5678"); Console.WriteLine("Intermediary started, and waiting for messages"); // proxy messages between frontend / backend var proxy = new Proxy(xsubSocket, xpubSocket); // blocks indefinitely proxy.Start(); } ``` -------------------------------- ### Example OutgoingSocketExtensions Send Implementation Source: https://github.com/zeromq/netmq/blob/master/docs/receiving-sending.md An example implementation of a Send extension method for IOutgoingSocket that sends a string using a specified encoding and options. This demonstrates how to convert a string to bytes and use the base Send method. ```csharp public static void Send(this IOutgoingSocket socket, string message, Encoding encoding, SendReceiveOptions options) { var msg = new Msg(); msg.InitPool(encoding.GetByteCount(message)); encoding.GetBytes(message, 0, message.Length, msg.Data, 0); socket.Send(ref msg, options); msg.Close(); } ``` -------------------------------- ### NetMQ Async/Await Server and Client Example in C# Source: https://github.com/zeromq/netmq/blob/master/docs/async-await.md Demonstrates asynchronous server and client operations using NetMQ's async/await capabilities. Requires NetMQRuntime for managing asynchronous tasks. The server sends messages after a delay, and the client sends messages and processes replies. ```csharp async Task ServerAsync() { using (var server = new RouterSocket("inproc://async")) { for (int i = 0; i < 1000; i++) { var (routingKey, more) = await server.ReceiveRoutingKeyAsync(); var (message, _) = await server.ReceiveFrameStringAsync(); // TODO: process message await Task.Delay(100); server.SendMoreFrame(routingKey); server.SendFrame("Welcome"); } } } async Task ClientAsync() { using (var client = new DealerSocket("inproc://async")) { for (int i = 0; i < 1000; i++) { client.SendFrame("Hello"); var (message, more) = await client.ReceiveFrameStringAsync(); // TODO: process reply await Task.Delay(100); } } } static void Main(string[] args) { using (var runtime = new NetMQRuntime()) { runtime.Run(ServerAsync(), ClientAsync()); } } ``` -------------------------------- ### Custom NetMQ ReceiveFrameString Implementation Example Source: https://github.com/zeromq/netmq/blob/master/docs/receiving-sending.md An example demonstrating how to implement a custom extension method for receiving a string frame from a NetMQ socket. It shows the process of receiving a raw message, extracting data, converting it to a string using the specified encoding, and handling message completion. ```csharp public static string ReceiveFrameString(this IReceivingSocket socket, Encoding encoding, out bool more) { var msg = new Msg(); msg.InitEmpty(); socket.Receive(ref msg); more = msg.HasMore; var str = msg.Size > 0 ? encoding.GetString(msg.Data, 0, msg.Size) : string.Empty; msg.Close(); return str; } ``` -------------------------------- ### NetMQ Publisher Socket Example (C#) Source: https://github.com/zeromq/netmq/blob/master/docs/xpub-xsub.md This code snippet demonstrates a publisher using NetMQ's PublisherSocket. It connects to a specified address and continuously sends messages with 'TopicA' or 'TopicB' prefixes. It includes configuration for SendHighWatermark and uses Random for message content. ```csharp using (var pubSocket = new PublisherSocket()) { pubSocket.Connect("tcp://127.0.0.1:5678"); Console.WriteLine("Publisher socket connecting..."); pubSocket.Options.SendHighWatermark = 1000; var rand = new Random(50); while (true) { var randomizedTopic = rand.NextDouble(); if (randomizedTopic > 0.5) { var msg = "TopicA msg-" + randomizedTopic; Console.WriteLine("Sending message : {0}", msg); pubSocket.SendMore("TopicA").Send(msg); } else { var msg = "TopicB msg-" + randomizedTopic; Console.WriteLine("Sending message : {0}", msg); pubSocket.SendMore("TopicB").Send(msg); } } } ``` -------------------------------- ### C# NetMQ Actor Communication Example Source: https://github.com/zeromq/netmq/blob/master/docs/actor.md This C# code demonstrates how to use the AccountActioner, which internally uses a NetMQ Actor, to perform account transactions. It shows starting the actor, sending credit transactions, and retrieving the updated account state. Ensure NetMQ library is referenced. ```csharp class Program { static void Main(string[] args) { // CommandActioner uses an NetMq.Actor internally var accountActioner = new AccountActioner(); var account = new Account(1, "Doron Somech", "112233", 0); PrintAccount(account); accountActioner.Start(); Console.WriteLine("Sending account to AccountActioner/Actor"); accountActioner.SendPayload(account, new AccountAction(TransactionType.Credit, 15)); account = accountActioner.GetPayLoad(); PrintAccount(account); accountActioner.Stop(); Console.WriteLine(); Console.WriteLine("Sending account to AccountActioner/Actor"); accountActioner.SendPayload(account, new AccountAction(TransactionType.Credit, 15)); PrintAccount(account); Console.ReadLine(); } static void PrintAccount(Account account) { Console.WriteLine("Account now"); Console.WriteLine(account); Console.WriteLine(); } } ``` -------------------------------- ### NetMQ Request-Response Client Example (C#) Source: https://github.com/zeromq/netmq/blob/master/docs/introduction.md Illustrates a NetMQ client using a RequestSocket to send messages and receive replies. The client connects to a server, sends 'Hello' ten times in a loop, and prints the received replies. Default send/receive operations are blocking. ```csharp using (var client = new RequestSocket()) { client.Connect("tcp://localhost:5555"); for (int i = 0; i < 10; i++) { Console.WriteLine("Sending Hello"); client.SendFrame("Hello"); var message = client.ReceiveFrameString(); Console.WriteLine("Received {0}", message); } } ``` -------------------------------- ### NetMQ Server Receiving Client Messages and Replying (C#) Source: https://github.com/zeromq/netmq/blob/master/docs/router-dealer.md Demonstrates a NetMQ server's ability to receive messages from clients, parse message frames, and send replies. This code is asynchronous and event-driven, meaning operations may not occur in a strictly sequential order. ```csharp Server receiving Socket : Frame[0] = c l i e n t 1 Server receiving Socket : Frame[1] = Server receiving Socket : Frame[2] = client 1 INCOMING CLIENT MESSAGE FROM CLIENT Server receiving Socket : Frame[0] = c l i e n t 0 Server receiving Socket : Frame[1] = Server receiving Socket : Frame[2] = client 0 REPLY client 1 back from server 08:05:56 REPLY client 0 back from server 08:05:56 ``` -------------------------------- ### NetMQ Non-Blocking Receive Example (C#) Source: https://github.com/zeromq/netmq/blob/master/docs/introduction.md Shows how to use `TryReceiveFrameString` for non-blocking message reception in NetMQ. This method attempts to receive a string message without waiting if no message is immediately available, returning `false` in that case. ```csharp string message; if (client.TryReceiveFrameString(out message)) Console.WriteLine("Received {0}", message); else Console.WriteLine("No message received"); ``` -------------------------------- ### NetMQ TCP Client-Server Communication (C#) Source: https://github.com/zeromq/netmq/blob/master/docs/transports.md Demonstrates a simple request-response pattern using NetMQ's TCP sockets. It shows how to bind a server socket and connect a client socket to exchange string messages. Ensure NetMQ library is installed. ```csharp using (var server = new ResponseSocket()) using (var client = new RequestSocket()) { server.Bind("tcp://*:5555"); client.Connect("tcp://localhost:5555"); Console.WriteLine("Sending Hello"); client.SendFrame("Hello"); var message = server.ReceiveFrameString(); Console.WriteLine("Received {0}", message); Console.WriteLine("Sending World"); server.SendFrame("World"); message = client.ReceiveFrameString(); Console.WriteLine("Received {0}", message); } ``` -------------------------------- ### NetMQ Request-Response Server Example (C#) Source: https://github.com/zeromq/netmq/blob/master/docs/introduction.md Demonstrates a basic NetMQ server using a ResponseSocket to receive messages and send replies. It binds to a TCP port and enters a loop to continuously process requests. Note that NetMQ does not include built-in serialization; string messages are handled directly. ```csharp using (var server = new ResponseSocket()) { server.Bind("tcp://*:5555"); while (true) { var message = server.ReceiveFrameString(); Console.WriteLine("Received {0}", message); // processing the request Thread.Sleep(100); Console.WriteLine("Sending World"); server.SendFrame("World"); } } ``` -------------------------------- ### Send Byte Array Messages in NetMQ C# Source: https://github.com/zeromq/netmq/wiki/Migrating-to-v4 Provides examples for sending byte arrays as messages using the IOutgoingSocket interface in NetMQ. It covers different overloads for sending data, including options for sending more frames and controlling message parts. ```csharp outgoingSocket.Send(byteArray); outgoingSocket.Send(byteArray, 0, byteArray.Length); outgoingSocket.SendMore(byteArray); outgoingSocket.SendMore(byteArray, 0, byteArray.Length); outgoingSocket.SendFrame(byteArray, false); outgoingSocket.SendMoreFrame(byteArray); outgoingSocket.TrySendFrame(TimeSpan.FromSeconds(1), byteArray, true); ``` -------------------------------- ### C# NetMQ Server-Client Communication with Router and Dealer Sockets Source: https://github.com/zeromq/netmq/blob/master/docs/router-dealer.md This C# code sets up a NetMQ server with a RouterSocket that binds to a TCP address. It also manages multiple client threads, each with a DealerSocket that connects to the server. The RouterSocket handles routing messages back to the correct client using client identities, while DealerSockets send and receive messages. Includes thread-local sockets for clients and a poller for asynchronous receive operations. ```csharp public static void Main(string[] args) { // NOTES // 1. Use ThreadLocal<DealerSocket> where each thread has // its own client DealerSocket to talk to server // 2. Each thread can send using it own socket // 3. Each thread socket is added to poller const int delay = 3000; // millis var clientSocketPerThread = new ThreadLocal<DealerSocket>(); using (var server = new RouterSocket("@tcp://127.0.0.1:5556")) using (var poller = new NetMQPoller()) { // Start some threads, each with its own DealerSocket // to talk to the server socket. Creates lots of sockets, // but no nasty race conditions no shared state, each // thread has its own socket, happy days. for (int i = 0; i < 3; i++) { Task.Factory.StartNew(state => { DealerSocket client = null; if (!clientSocketPerThread.IsValueCreated) { client = new DealerSocket(); client.Options.Identity = Encoding.Unicode.GetBytes(state.ToString()); client.Connect("tcp://127.0.0.1:5556"); client.ReceiveReady += Client_ReceiveReady; clientSocketPerThread.Value = client; poller.Add(client); } else { client = clientSocketPerThread.Value; } while (true) { var messageToServer = new NetMQMessage(); messageToServer.AppendEmptyFrame(); messageToServer.Append(state.ToString()); Console.WriteLine("======================================"); Console.WriteLine(" OUTGOING MESSAGE TO SERVER "); Console.WriteLine("======================================"); PrintFrames("Client Sending", messageToServer); client.SendMultipartMessage(messageToServer); Thread.Sleep(delay); } }, string.Format("client {0}", i), TaskCreationOptions.LongRunning); } // start the poller poller.RunAsync(); // server loop while (true) { var clientMessage = server.ReceiveMessage(); Console.WriteLine("======================================"); Console.WriteLine(" INCOMING CLIENT MESSAGE FROM CLIENT "); Console.WriteLine("======================================"); PrintFrames("Server receiving", clientMessage); if (clientMessage.FrameCount == 3) { var clientAddress = clientMessage[0]; var clientOriginalMessage = clientMessage[2].ConvertToString(); string response = string.Format("{0} back from server {1}", clientOriginalMessage, DateTime.Now.ToLongTimeString()); var messageToClient = new NetMQMessage(); messageToClient.Append(clientAddress); messageToClient.AppendEmptyFrame(); messageToClient.Append(response); server.SendMultipartMessage(messageToClient); } } } } void PrintFrames(string operationType, NetMQMessage message) { for (int i = 0; i < message.FrameCount; i++) { Console.WriteLine("{0} Socket : Frame[{1}] = {2}", operationType, i, message[i].ConvertToString()); } } void Client_ReceiveReady(object sender, NetMQSocketEventArgs e) { bool hasmore = false; e.Socket.Receive(out hasmore); if (hasmore) { string result = e.Socket.ReceiveFrameString(out hasmore); Console.WriteLine("REPLY {0}", result); } } ``` -------------------------------- ### C# Bank Account Data Structure for Threading Source: https://github.com/zeromq/netmq/blob/master/docs/actor.md Defines a simple C# class representing a bank account with properties like ID, name, sort code, and balance. This class is used in subsequent examples to demonstrate concurrent access and manipulation by multiple threads. ```csharp public class Account { public Account(int id, string name, string sortCode, decimal balance) { Id = id; Name = name; SortCode = sortCode; Balance = balance; } public int Id { get; set; } public string Name { get; set; } public string SortCode { get; set; } public decimal Balance { get; set; } public override string ToString() { return string.Format("Id: {0}, Name: {1}, SortCode: {2}, Balance: {3}", Id, Name, SortCode, Balance); } } ``` -------------------------------- ### NetMQ InProc Communication Between Threads (C#) Source: https://github.com/zeromq/netmq/blob/master/docs/transports.md Illustrates inter-thread communication using NetMQ's InProc sockets. This example shows how two threads within the same process can send and receive string messages via a pair socket. Requires NetMQ library. ```csharp using (var end1 = new PairSocket()) using (var end2 = new PairSocket()) { end1.Bind("inproc://inproc-demo"); end2.Connect("inproc://inproc-demo"); var end1Task = Task.Run(() => { Console.WriteLine("ThreadId = {0}", Thread.CurrentThread.ManagedThreadId); Console.WriteLine("Sending hello down the inproc pipeline"); end1.SendFrame("Hello"); }); var end2Task = Task.Run(() => { Console.WriteLine("ThreadId = {0}", Thread.CurrentThread.ManagedThreadId); var message = end2.ReceiveFrameString(); Console.WriteLine(message); }); Task.WaitAll(new[] { end1Task, end2Task }); } ``` -------------------------------- ### Receive Single Frame as byte[] with NetMQ Source: https://github.com/zeromq/netmq/wiki/Migrating-to-v4 Provides methods for receiving a single message frame as a byte array. Overloads include options for specifying send/receive behavior, retrieving a boolean indicating success, and setting timeouts. `ReceiveFrameBytes` offers a direct way to get frame data. ```csharp public interface IReceivingSocket { byte[] Receive(); byte[] Receive(out bool hasMore); byte[] Receive(bool dontWait, out bool hasMore); byte[] Receive(SendReceiveOptions options); byte[] Receive(SendReceiveOptions options, out bool hasMore); byte[] Receive(TimeSpan timeout); byte[] ReceiveFrameBytes(); byte[] ReceiveFrameBytes(out bool hasMore); bool TryReceiveFrameBytes(out byte[] frame); bool TryReceiveFrameBytes(out byte[] frame, out bool hasMore); bool TryReceiveFrameBytes(TimeSpan timeout, out byte[] frame); bool TryReceiveFrameBytes(TimeSpan timeout, out byte[] frame, out bool hasMore); } ``` -------------------------------- ### NetMQ Ventilator Task Sender (C#) Source: https://github.com/zeromq/netmq/blob/master/docs/push-pull.md The Ventilator acts as a task generator, pushing work items to worker processes. It binds a PushSocket to a specific address and sends tasks, simulating work by sending random sleep durations. It also communicates with a 'Sink' to signal the start of a task batch. ```csharp using System; using NetMQ; namespace Ventilator { public class Program { public static void Main(string[] args) { // Task Ventilator // Binds PUSH socket to tcp://localhost:5557 // Sends batch of tasks to workers via that socket Console.WriteLine("====== VENTILATOR ======"); using (var sender = new PushSocket("@tcp://*:5557")) using (var sink = new PushSocket(">tcp://localhost:5558")) { Console.WriteLine("Press enter when worker are ready"); Console.ReadLine(); //the first message it "0" and signals start of batch //see the Sink.csproj Program.cs file for where this is used Console.WriteLine("Sending start of batch to Sink"); sink.SendFrame("0"); Console.WriteLine("Sending tasks to workers"); //initialise random number generator Random rand = new Random(0); //expected costs in Ms int totalMs = 0; //send 100 tasks (workload for tasks, is just some random sleep time that //the workers can perform, in real life each work would do more than sleep for (int taskNumber = 0; taskNumber < 100; taskNumber++) { //Random workload from 1 to 100 msec int workload = rand.Next(0, 100); totalMs += workload; Console.WriteLine("Workload : {0}", workload); sender.SendFrame(workload.ToString()); } Console.WriteLine("Total expected cost : {0} msec", totalMs); Console.WriteLine("Press Enter to quit"); Console.ReadLine(); } } } } ``` -------------------------------- ### NetMQ Poller: Servicing Multiple Response Sockets with ReceiveReady Source: https://github.com/zeromq/netmq/blob/master/docs/poller.md This example demonstrates how to use NetMQPoller to service multiple ResponseSockets concurrently from a single thread. Event handlers are attached to the ReceiveReady event of each socket, allowing for non-blocking message processing when data is available. ```csharp using (var rep1 = new ResponseSocket("@tcp://*:5001")) using (var rep2 = new ResponseSocket("@tcp://*:5002")) using (var poller = new NetMQPoller { rep1, rep2 }) { // these event will be raised by the Poller rep1.ReceiveReady += (s, a) => { // receive won't block as a message is ready string msg = a.Socket.ReceiveString(); // send a response a.Socket.Send("Response"); }; rep2.ReceiveReady += (s, a) => { // receive won't block as a message is ready string msg = a.Socket.ReceiveString(); // send a response a.Socket.Send("Response"); }; // start polling (on this thread) poller.Run(); } ``` -------------------------------- ### NetMQ Poller: Limit Batched Message Processing Source: https://github.com/zeromq/netmq/blob/master/docs/poller.md Provides an example of limiting the number of messages processed in a single batch when using TryReceiveFrameString within a NetMQPoller's ReceiveReady event. This prevents message starvation of other sockets on the poller when one socket is under a continuous high load. ```csharp rep1.ReceiveReady += (s, a) => { string msg; // receiving 1000 messages or less if not available for (int count = 0; count < 1000; i++) { // exit the for loop if failed to receive a message if (!a.Socket.TryReceiveFrameString(out msg)) break; // send a response a.Socket.Send("Response"); } }; ``` -------------------------------- ### NetMQ Sink: Collecting Results and Measuring Performance (C#) Source: https://github.com/zeromq/netmq/blob/master/docs/push-pull.md The NetMQ Sink component aggregates results from multiple workers. It binds a PULL socket to listen for completion signals from workers. The Sink synchronizes with the start of a batch and then collects a predefined number of messages, measuring the total elapsed time for the batch. This is useful for performance monitoring and validating the distributed processing. ```csharp using System; using System.Diagnostics; using System.Threading; using System.Threading.Tasks; using NetMQ; namespace Sink { public class Program { public static void Main(string[] args) { // Task Sink // Bindd PULL socket to tcp://localhost:5558 // Collects results from workers via that socket Console.WriteLine("====== SINK ======"); //socket to receive messages on using (var receiver = new PullSocket("@tcp://localhost:5558")) { //wait for start of batch (see Ventilator.csproj Program.cs) var startOfBatchTrigger = receiver.ReceiveFrameString(); Console.WriteLine("Seen start of batch"); //Start our clock now var watch = Stopwatch.StartNew(); for (int taskNumber = 0; taskNumber < 100; taskNumber++) { var workerDoneTrigger = receiver.ReceiveFrameString(); if (taskNumber % 10 == 0) { Console.Write(":"); } else { Console.Write("."); } } watch.Stop(); //Calculate and report duration of batch Console.WriteLine(); Console.WriteLine("Total elapsed time {0} msec", watch.ElapsedMilliseconds); Console.ReadLine(); } } } } ``` -------------------------------- ### NetMQ Worker: Task Processing and Result Sending (C#) Source: https://github.com/zeromq/netmq/blob/master/docs/push-pull.md The NetMQ Worker component acts as a task consumer. It connects to a PULL socket to receive workload from a 'Ventilator' and a PUSH socket to send completion signals to a 'Sink'. The workload is simulated by a sleep duration, and upon completion, an empty message is sent to the Sink. This setup is crucial for distributed processing where tasks are offloaded to multiple workers. ```csharp using System; using System.Threading; using NetMQ; namespace Worker { public class Program { public static void Main(string[] args) { // Task Worker // Connects PULL socket to tcp://localhost:5557 // collects workload for socket from Ventilator via that socket // Connects PUSH socket to tcp://localhost:5558 // Sends results to Sink via that socket Console.WriteLine("====== WORKER ======"); using (var receiver = new PullSocket(">tcp://localhost:5557")) using (var sender = new PushSocket(">tcp://localhost:5558")) { //process tasks forever while (true) { //workload from the ventilator is a simple delay //to simulate some work being done, see //Ventilator.csproj Program.cs for the workload sent //In real life some more meaningful work would be done string workload = receiver.ReceiveFrameString(); //simulate some work being done Thread.Sleep(int.Parse(workload)); //send results to sink, sink just needs to know worker //is done, message content is not important, just the presence of //a message means worker is done. //See Sink.csproj Program.cs Console.WriteLine("Sending to Sink"); sender.SendFrame(string.Empty); } } } } } ``` -------------------------------- ### NetMQ Socket Creation: Version 3 vs Version 4 Source: https://github.com/zeromq/netmq/wiki/Migrating-to-v4 Demonstrates the change in NetMQ socket creation from version 3, which used a NetMQContext, to version 4, which uses direct constructor instantiation. This change simplifies socket management. ```csharp using (var context = NetMQContext.Create()) using (var publisher = context.CreatePublisherSocket()) { // ... } ``` ```csharp using (var publisher = new PublisherSocket()) { // ... } ``` -------------------------------- ### NetMQ SubscriberSocket Connection and Message Reception (C#) Source: https://github.com/zeromq/netmq/blob/master/docs/xpub-xsub.md This C# snippet shows how to initialize a SubscriberSocket, connect it to a publisher's address, configure the ReceiveHighWatermark option, subscribe to a specified topic, and enter a loop to continuously receive and print messages. It assumes the publisher is sending messages in a topic-message pair format. Error handling and graceful shutdown are not included. ```csharp string topic = /* ... */; // one of "TopicA" or "TopicB" using (var subSocket = new SubscriberSocket()) { subSocket.Connect("tcp://127.0.0.1:1234"); subSocket.Options.ReceiveHighWatermark = 1000; subSocket.Subscribe(topic); Console.WriteLine("Subscriber socket connecting..."); while (true) { string messageTopicReceived = subSocket.ReceiveString(); string messageReceived = subSocket.ReceiveString(); Console.WriteLine(messageReceived); } } ``` -------------------------------- ### NetMQ Poller Initialization with Collection Initializer Source: https://github.com/zeromq/netmq/wiki/Migrating-to-v4 Illustrates how to initialize the NetMQPoller using collection initializer syntax in version 4, which allows for a more concise way to add multiple sockets and timers. ```csharp new NetMQPoller { publisher, subscriber, timer, tcpSocket } ``` -------------------------------- ### Publishing Messages with Topics in C# Source: https://github.com/zeromq/netmq/blob/master/docs/pub-sub.md Demonstrates how to send messages with a specified topic using NetMQ's PublisherSocket. The topic must be sent as the first frame in a multipart message, followed by the message payload. This enables subscribers to filter messages based on their interests. ```csharp // send a message on the 'status' topic pub.SendMoreFrame("status").SendFrame("All is well"); ``` -------------------------------- ### C# NetMQ PGM Publisher/Subscriber with Options Source: https://github.com/zeromq/netmq/blob/master/docs/transports.md This C# code snippet demonstrates setting up and using NetMQ's PublisherSocket and SubscriberSocket with the PGM protocol. It configures multicast-related options such as hops, rate, recovery interval, and send/receive buffers. It also shows how to connect, bind, subscribe, send, and receive messages. ```csharp const int MegaBit = 1024; const int MegaByte = 1024; using (var pub = new PublisherSocket()) using (var sub1 = new SubscriberSocket()) using (var sub2 = new SubscriberSocket()) { pub.Options.MulticastHops = 2; pub.Options.MulticastRate = 40 * MegaBit; // 40 megabit pub.Options.MulticastRecoveryInterval = TimeSpan.FromMinutes(10); pub.Options.SendBuffer = MegaByte * 10; // 10 megabyte pub.Connect("pgm://224.0.0.1:5555"); sub1.Options.ReceiveBuffer = MegaByte * 10; sub1.Bind("pgm://224.0.0.1:5555"); sub1.Subscribe(""); sub2.Bind("pgm://224.0.0.1:5555"); sub2.Options.ReceiveBuffer = MegaByte * 10; sub2.Subscribe(""); Console.WriteLine("Server sending 'Hi'"); pub.Send("Hi"); bool more; Console.WriteLine("sub1 received = '{0}'", sub1.ReceiveString(out more)); Console.WriteLine("sub2 received = '{0}'", sub2.ReceiveString(out more)); } ``` -------------------------------- ### NetMQ - Building a Multipart Message Object in C# Source: https://github.com/zeromq/netmq/blob/master/docs/message.md Demonstrates how to construct a multipart message in NetMQ using the NetMQMessage class. Frames are appended individually using various overloads of the Append method before sending the entire message. ```csharp var message = new NetMQMessage(); message.Append("IAmFrame0"); message.Append("IAmFrame1"); server.SendMessage(message); ``` -------------------------------- ### NetMQ Socket Event Args C# Source: https://github.com/zeromq/netmq/wiki/Migrating-to-v4 Explains the usage of NetMQSocketEventArgs for checking the readiness of sockets for receiving or sending operations. It highlights the transition from older properties to newer, more descriptive ones. ```csharp if (args.IsReadyToReceive) { /* Handle receive */ } if (args.IsReadyToSend) { /* Handle send */ } ``` -------------------------------- ### NetMQ Cleanup in Main Application (C#) Source: https://github.com/zeromq/netmq/blob/master/docs/cleanup.md Demonstrates the recommended way to ensure NetMQ library cleanup in a C# application's main method. It uses a `try-finally` block to guarantee that `NetMQConfig.Cleanup()` is called, preventing potential deadlocks if sockets are not properly disposed. ```csharp static void Main(string[] args) { try { // Do your logic here } finally { NetMQConfig.Cleanup(); } } ``` -------------------------------- ### C# NetMQ Subscriber Implementation Source: https://github.com/zeromq/netmq/blob/master/docs/pub-sub.md This C# code implements a NetMQ subscriber that connects to a local publisher, subscribes to specified topics (or all topics), and continuously receives and prints messages. It uses the NetMQ library and requires a publisher to be running on the same machine. ```csharp using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using NetMQ; using NetMQ.Sockets; namespace SubscriberA { class Program { public static IList<string> allowableCommandLineArgs = new [] { "TopicA", "TopicB", "All" }; static void Main(string[] args) { if (args.Length != 1 || !allowableCommandLineArgs.Contains(args[0])) { Console.WriteLine("Expected one argument, either " + "'TopicA', 'TopicB' or 'All'"); Environment.Exit(-1); } string topic = args[0] == "All" ? "" : args[0]; Console.WriteLine("Subscriber started for Topic : {0}", topic); using (var subSocket = new SubscriberSocket()) { subSocket.Options.ReceiveHighWatermark = 1000; subSocket.Connect("tcp://localhost:12345"); subSocket.Subscribe(topic); Console.WriteLine("Subscriber socket connecting..."); while (true) { string messageTopicReceived = subSocket.ReceiveFrameString(); string messageReceived = subSocket.ReceiveFrameString(); Console.WriteLine(messageReceived); } } } } } ``` -------------------------------- ### Subscribing to Topics in C# Source: https://github.com/zeromq/netmq/blob/master/docs/pub-sub.md Illustrates how to subscribe to specific topics using NetMQ's SubscriberSocket. The Subscribe method takes a topic string, and the socket will then receive messages whose topic frames match this subscription using a prefix check. An empty topic string subscribes to all messages. ```csharp // subscribe to the 'status' topic sub.Subscribe("status"); ``` ```csharp sub.Subscribe(""); // subscribe to all topics ``` -------------------------------- ### NetMQ Cleanup in NUnit Tests (C#) Source: https://github.com/zeromq/netmq/blob/master/docs/cleanup.md Shows how to implement NetMQ cleanup in NUnit tests using a `SetUpFixture` and `OneTimeTearDown`. The `NetMQConfig.Cleanup(false)` call with `block` set to false is crucial here to prevent test hangs in case of failing tests. ```csharp [SetUpFixture] public class Setup { [OneTimeTearDown] public void TearDown() { NetMQConfig.Cleanup(false); } } ``` -------------------------------- ### NetMQ - Sending Multipart Messages Frame by Frame in C# Source: https://github.com/zeromq/netmq/blob/master/docs/message.md Illustrates an alternative method for sending multipart messages in NetMQ by chaining SendMoreFrame calls, ending with SendFrame. This approach is suitable for sending byte arrays and strings. ```csharp server.SendMoreFrame("IAmFrame0") .SendFrame("IAmFrame1"); ``` -------------------------------- ### Send NetMQMessage in NetMQ C# Source: https://github.com/zeromq/netmq/wiki/Migrating-to-v4 Demonstrates sending a complete NetMQMessage, which can contain multiple frames, using the IOutgoingSocket interface. This includes methods for sending the entire message or attempting to send it within a specified timeout. ```csharp NetMQMessage message = new NetMQMessage(); message.Append("Frame1"); message.Append("Frame2"); outgoingSocket.SendMessage(message, false); outgoingSocket.SendMultipartMessage(message); outgoingSocket.TrySendMultipartMessage(TimeSpan.FromSeconds(5), message); ``` -------------------------------- ### Send String Messages in NetMQ C# Source: https://github.com/zeromq/netmq/wiki/Migrating-to-v4 Illustrates how to send string messages using the IOutgoingSocket interface in NetMQ, supporting various encodings and send options. This includes sending single frames or multiple frames with additional options. ```csharp outgoingSocket.Send("Hello"); outgoingSocket.Send("World", Encoding.UTF8, true, true); outgoingSocket.SendMore("Hello", Encoding.UTF8, true); outgoingSocket.SendFrame("MessagePart", false); outgoingSocket.SendMoreFrame("AnotherPart"); outgoingSocket.TrySendFrame(TimeSpan.FromSeconds(1), "TimeoutTest", true); ``` -------------------------------- ### Simple NetMQ Server using ResponseSocket Source: https://github.com/zeromq/netmq/blob/master/docs/poller.md A basic NetMQ server implementation using ResponseSocket that continuously listens for and responds to incoming messages. It demonstrates a straightforward, infinite loop for processing requests. ```csharp using (var rep = new ResponseSocket("@tcp://*:5002")) { // process requests, forever... while (true) { // receive a request message var msg = rep.ReceiveFrameString(); // send a canned response rep.Send("Response"); } } ``` -------------------------------- ### NetMQ Relaxed Request/Reply in C# Source: https://github.com/zeromq/netmq/blob/master/docs/request-response.md This C# snippet demonstrates how to configure a `RequestSocket` with `Correlate` and `Relaxed` options to send multiple requests before receiving a response. The response received will be for the last request sent. This code requires the NetMQ library. ```csharp using (var rep = new ResponseSocket()) using (var req = new RequestSocket()) { var port = rep.BindRandomPort($"tcp://127.0.0.1"); req.Connect($"tcp://127.0.0.1:{port}"); req.Options.Correlate = correlate; // Assuming 'correlate' is defined elsewhere req.Options.Relaxed = true; req.SendFrame("Request1"); req.SendFrame("Request2"); rep.SendFrame(rep.ReceiveFrameString()); rep.SendFrame(rep.ReceiveFrameString()); // the result here will be "Request2". Console.WriteLine(req.ReceiveFrameString()); } ``` -------------------------------- ### C#: Receive Entire Messages with NetMQ Source: https://github.com/zeromq/netmq/blob/master/docs/message.md Shows how to receive an entire NetMQ message, containing all its frames, at once using the ReceiveMultipartMessage method. This simplifies handling multi-frame messages by returning a NetMQMessage object. It also mentions alternative methods for receiving all frames as strings or byte arrays. ```csharp NetMQMessage message = client.ReceiveMultipartMessage(); Console.WriteLine("message.FrameCount={0}", message.FrameCount); Console.WriteLine("message[0]={0}", message[0].ConvertToString()); Console.WriteLine("message[1]={0}", message[1].ConvertToString()); ``` ```csharp IEnumerable<string> framesAsStrings = client.ReceiveMultipartStrings(); ``` ```csharp IEnumerable<byte[]> framesAsByteArrays = client.ReceiveMultipartBytes(); ``` -------------------------------- ### Receive Entire Multipart Message as List<string> with NetMQ Source: https://github.com/zeromq/netmq/wiki/Migrating-to-v4 Allows receiving an entire multipart message as a list of strings. Methods include `ReceiveStringMessages` with encoding and capacity options, and `ReceiveAllString` for a general approach. `ReceiveMultipartStrings` and its variants offer flexibility in handling multipart string messages. ```csharp public interface IReceivingSocket { List<string> ReceiveStringMessages(int capacity); List<string> ReceiveStringMessages(Encoding encoding, int capacity); List<string> ReceiveAllString(); List<string> ReceiveMultipartStrings(); List<string> ReceiveMultipartStrings(out bool hasMore); bool TryReceiveMultipartStrings(ref List<string> message, int capacity); bool TryReceiveMultipartStrings(Encoding encoding, ref List<string> message, int capacity); bool TryReceiveMultipartStrings(TimeSpan timeout, ref List<string> message, int capacity); bool TryReceiveMultipartStrings(TimeSpan timeout, Encoding encoding, ref List<string> message, int capacity); } ``` -------------------------------- ### Receive Single Frame as Msg with NetMQ Source: https://github.com/zeromq/netmq/wiki/Migrating-to-v4 Demonstrates how to receive a single message frame using the `Msg` object. This method is part of the `IReceivingSocket` interface and can be used with or without sending options. A `TryReceive` overload is available for timed operations. ```csharp public interface IReceivingSocket { void Receive(ref Msg msg, SendReceiveOptions options); bool TryReceive(ref Msg msg, TimeSpan timeout); } ```