IpcNetMq 26.2.1

dotnet add package IpcNetMq --version 26.2.1
                    
NuGet\Install-Package IpcNetMq -Version 26.2.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="IpcNetMq" Version="26.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="IpcNetMq" Version="26.2.1" />
                    
Directory.Packages.props
<PackageReference Include="IpcNetMq" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add IpcNetMq --version 26.2.1
                    
#r "nuget: IpcNetMq, 26.2.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package IpcNetMq@26.2.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=IpcNetMq&version=26.2.1
                    
Install as a Cake Addin
#tool nuget:?package=IpcNetMq&version=26.2.1
                    
Install as a Cake Tool

IPC Communications using NetMQ (ZeroMQ)

Version: 26.1.14 - Tightened up some async handling. Put in error check to check for Server mode. Test: Turnaround time for a REQ-REP call is consistently 120 microseconds (0.12 ms) on machine (11th Gen Intel(R) Core(TM) i9-11900K @ 3.50GHz (3.40 GHz)

A concrete implementation of using ZeroMQ REQ-REP package/pattern. The advantantage over mixed language 'call' is separate processes, is a quick implementation, easy to debug, version protection, cross framework, cross-platform, cross-language. Advantage over other IPC is simplicity and speed (90-150 microseconds per roundtrip call).

The Client makes a Remote Procedure Call (RPC) by sending an IpcPacket to a Server. Within the packet is the name of the Procedure (Action) and the arguments (a list of name/value pairs in the Request string) and also what is expected in the Reply (another list of name/value pairs).

The Server processes the procedure/method logic (named Action) according to those Request arguments and fills in the Reply.

Both the Request and Reply strings are serialized json, and any values are strings. Json and string are common denominator that can be processed by most modern languages and byte-order issues are avoided.

Everything revolves around the information packet called IpcPacket that is constructed to handle most cases that I have encountered in my career.

The header holds things like a schema-version, timestamp, action name, and sequence number to help with communication errors. Again, the Request string is a json-serialized list of name/value pairs (the 'in' arguments), and a Reply string (also json-serialized list of name/value pairs).

It is assumed that type information for values is implicitly known by the Server/Clients.

Examples are given for C# and Python, with near-term plans for C++ and Java.

Benchmarks indicate approximately 90-120 microseconds for a REQ-REP roundtrip 'call'. For reference, an actual in-process call between Python and C# would take about 10-20 microseconds, so, about 11x slower, but with the advantage of separate processes, separate languages, separate runtimes, and no need for wrappers or interop layers.

Use cases: The REQ-REP pattern in general - and ZeroMQ/NetMQ specifically - along with generic strings and accepted serialization makes for a good combination for inter-process (indeed, even inter-machine) calls.

Anyone who has tried to call python from C# knows the difficult issues involved. IpcNetMq provides a simple way around this. For example, a C# program may need results from a python library (which is a vast landscape). You can use the included python IpcNetMq server to allow this call, and not need to worry about bit-size, byte-order, language versions, etc. or building wrappers around the calls.

The downside is that you will sacrifice about 11x speed, but less than 0.1 millisecond turnaround should be sufficient for many applications (e.g. I am using it for communications with my rower and also for Stride 3D communications)

Test Examples are included but there is a quick display of the salient parts of the client and server in the C# example.

**** Client using var client = new IpcClientNetMq(clientName, serverAddress) { LoggingLevel = 1 }; while (!cts.IsCancellationRequested) { try { simTime += pollIntervalMs / 1000.0;

                // Build one request (dispatcher will assign SequenceNumber)
                var request = new IpcPacket
                {
                    Action = "do_get1", // or "do_getStrokeData" per your server
                    ContextString = JsonHelpers.BuildNameValuePairs(("SimTime", $"{simTime:0.0}")),
                    RequestString = JsonHelpers.BuildNameValuePairs(("Value1", "10"), ("Value2", "23.4")),
                    ReplyString = JsonHelpers.BuildNameValuePairs(("Result1", ""), ("Result2", ""))
                };

                var reply =
                    await client.CallIpcMethodAsync(
                        request,
                        sendTimeout: sendTimeout,
                        receiveTimeout: receiveTimeout,
                        ct: cts.Token);

                packetsSent++;

**** Server

            var server = new IpcServerNetMq("TestServer", ipcAddress);
            server.RunIpcServerLoop(UserActions.HandleAction);

where HandleAction might be something like: public static IpcPacket HandleAction(IpcPacket inPacket) { switch (inPacket.Action) { case "do_get1": return UserActions.do_get1(inPacket); case "do_get2": return UserActions.do_get2(inPacket); case "TestEnter": return UserActions.TestEnter(inPacket); case "TestExit": return UserActions.TestExit(inPacket);

            default:

At any rate, enjoy and I hope it helps.

Cheers, Daniel

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Framework net48 is compatible.  net481 was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
26.2.1 93 2/1/2026
26.1.9 110 1/10/2026
26.1.8 102 1/8/2026
26.1.6 97 1/8/2026
25.11.19 416 11/19/2025
1.0.0 417 11/19/2025

Updates to the client robustnes. Removed unneeded GDI reference. Timings are at 500 microSeconds RTT