Skip to content

Commit

Permalink
Update docs with new APIs.
Browse files Browse the repository at this point in the history
  • Loading branch information
drewnoakes committed Jan 13, 2016
1 parent 06bc8db commit a63b9ee
Show file tree
Hide file tree
Showing 12 changed files with 247 additions and 376 deletions.
11 changes: 2 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,9 @@ There are also a few blog posts available, which you can read about here:
Here is a simple example:

```csharp
using (var context = NetMQContext.Create())
using (var server = context.CreateResponseSocket())
using (var client = context.CreateRequestSocket())
using (var server = new ResponseSocket("@tcp://localhost:5556")) // bind
using (var client = new RequestSocket(">tcp://localhost:5556")) // connect
{
// Bind the server to a local TCP address
server.Bind("tcp://localhost:5556");

// Connect the client to the server
client.Connect("tcp://localhost:5556");

// Send a message from the client socket
client.SendFrame("Hello");

Expand Down
25 changes: 5 additions & 20 deletions docs/actor.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,15 +199,9 @@ Anyway here is the `Actor` code:
{
public class ShimHandler : IShimHandler<object>
{
private readonly NetMQContext context;
private PairSocket shim;
private Poller poller;

public ShimHandler(NetMQContext context)
{
this.context = context;
}

public void Initialise(object state)
{
}
Expand All @@ -218,9 +212,8 @@ Anyway here is the `Actor` code:
shim.ReceiveReady += OnShimReady;
shim.SignalOK();

poller = new Poller();
poller.AddSocket(shim);
poller.Start();
poller = new NetMQPoller { shim };
poller.Run();
}

private void OnShimReady(object sender, NetMQSocketEventArgs e)
Expand All @@ -231,7 +224,7 @@ Anyway here is the `Actor` code:
{
case ActorKnownMessages.END_PIPE:
Console.WriteLine("Actor received END_PIPE message");
poller.Stop(false);
poller.Stop();
break;
case "AmmendAccount":
Console.WriteLine("Actor received AmmendAccount message");
Expand Down Expand Up @@ -265,19 +258,13 @@ Anyway here is the `Actor` code:
}

private Actor<object> actor;
private readonly NetMQContext context;

public AccountActioner(NetMQContext context)
{
this.context = context;
}

public void Start()
{
if (actor != null)
return;

actor = new Actor<object>(context, new ShimHandler(context), null);
actor = new Actor<object>(new ShimHandler(), null);
}

public void Stop()
Expand Down Expand Up @@ -318,10 +305,8 @@ You would communicate with this `Actor` code using something like the following.
{
static void Main(string[] args)
{
var context = NetMQContext.Create();

// CommandActioner uses an NetMq.Actor internally
var accountActioner = new AccountActioner(context);
var accountActioner = new AccountActioner();

var account = new Account(1, "Doron Semech", "112233", 0);
PrintAccount(account);
Expand Down
78 changes: 36 additions & 42 deletions docs/beacon.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,33 +66,31 @@ to discover one another, configured only via a shared port number.
}
}

private readonly NetMQContext m_context;
private readonly int m_broadcastPort;

private NetMQActor m_actor;

private PublisherSocket m_publisher;
private SubscriberSocket m_subscriber;
private NetMQBeacon m_beacon;
private Poller m_poller;
private NetMQPoller m_poller;
private PairSocket m_shim;
private Dictionary<NodeKey, DateTime> m_nodes;

private Bus(NetMQContext context, int broadcastPort)
private Bus(int broadcastPort)
{
m_nodes = new Dictionary<NodeKey, DateTime>();
m_context = context;
m_broadcastPort = broadcastPort;
m_actor = NetMQActor.Create(context, RunActor);
m_actor = NetMQActor.Create(RunActor);
}

/// <summary>
/// Creates a new message bus actor. All communication with the bus is
/// through the returned <see cref="NetMQActor"/>.
/// </summary>
public static NetMQActor Create(NetMQContext context, int broadcastPort)
public static NetMQActor Create(int broadcastPort)
{
Bus node = new Bus(context, broadcastPort);
Bus node = new Bus(broadcastPort);
return node.m_actor;
}

Expand All @@ -102,9 +100,9 @@ to discover one another, configured only via a shared port number.
m_shim = shim;

// create all subscriber, publisher and beacon
using (m_subscriber = m_context.CreateSubscriberSocket())
using (m_publisher = m_context.CreatePublisherSocket())
using (m_beacon = new NetMQBeacon(m_context))
using (m_subscriber = new SubscriberSocket())
using (m_publisher = new PublisherSocket())
using (m_beacon = new NetMQBeacon())
{
// listen to actor commands
m_shim.ReceiveReady += OnShimReady;
Expand All @@ -131,20 +129,19 @@ to discover one another, configured only via a shared port number.
// listen to incoming beacons
m_beacon.ReceiveReady += OnBeaconReady;

// Create and configure the poller with all sockets
m_poller = new Poller(m_shim, m_subscriber, m_beacon);

// Create a timer to clear dead nodes
NetMQTimer timer = new NetMQTimer(TimeSpan.FromSeconds(1));
timer.Elapsed += ClearDeadNodes;
m_poller.AddTimer(timer);

// Create and configure the poller with all sockets and the timer
m_poller = new NetMQPoller { m_shim, m_subscriber, m_beacon, timer };

// signal the actor that we finished with configuration and
// ready to work
m_shim.SignalOK();

// polling until cancelled
m_poller.PollTillCancelled();
m_poller.Run();
}
}

Expand All @@ -157,7 +154,7 @@ to discover one another, configured only via a shared port number.
if (command == NetMQActor.EndShimMessage)
{
// we cancel the socket which dispose and exist the shim
m_poller.Cancel();
m_poller.Stop();
}
else if (command == PublishCommand)
{
Expand Down Expand Up @@ -224,37 +221,34 @@ to discover one another, configured only via a shared port number.
A node on the bus might resemble:

:::csharp
using (NetMQContext context = NetMQContext.Create())
{
// create a bus using broadcast port 9999
var actor = Bus.Create(context, 9999);
// create a bus using broadcast port 9999
var actor = Bus.Create(9999);

// beacons publish every second, so wait a little longer than that to
// let all the other nodes connect to our new node
Thread.Sleep(1100);
// beacons publish every second, so wait a little longer than that to
// let all the other nodes connect to our new node
Thread.Sleep(1100);

// publish a hello message
// note we can use NetMQSocket send and receive extension methods
actor.SendMore(Bus.PublishCommand).Send("Hello?");
// publish a hello message
// note we can use NetMQSocket send and receive extension methods
actor.SendMoreFrame(Bus.PublishCommand).SendFrame("Hello?");

// receive messages from other nodes on the bus
while (true)
{
string message = actor.ReceiveString();
// receive messages from other nodes on the bus
while (true)
{
string message = actor.ReceiveFrameString();

if (message == "Hello?")
{
// another node is saying hello
Console.WriteLine(message);
if (message == "Hello?")
{
// another node is saying hello
Console.WriteLine(message);

// send back a welcome message
actor.SendMore(Bus.PublishCommand).Send("Welcome!");
}
else
{
// it's probably a welcome message
Console.WriteLine(message);
}
// send back a welcome message
actor.SendMoreFrame(Bus.PublishCommand).SendFrame("Welcome!");
}
else
{
// it's probably a welcome message
Console.WriteLine(message);
}
}

Expand Down
45 changes: 12 additions & 33 deletions docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,12 @@ The philosophy of ZeroMQ starts with the _zero_. The zero is for zero broker (Ze

More generally, "zero" refers to the culture of minimalism that permeates the project. We add power by removing complexity rather than by exposing new functionality.


## Getting the library

You can get NetMQ library from [NuGet](https://nuget.org/packages/NetMQ/).


## Context

The `NetMQContext` is used to create _all_ sockets. Therefore any NetMQ code should start by calling `NetMQContext.Create()` to create an instance.

`NetMQContext` is `IDisposable` so can be used within a `using` block:

:::csharp
using (var context = NetMQContext.Create())
{
// code in here. exit this block to dispose the context,
// only when communication is no longer required
}

You should create and use exactly _one_ context in your process. Technically, the context is the container for all sockets in process, and acts as the transport for inproc sockets (the fastest way to connect the threads in process). If at runtime a process has two contexts, these are like separate NetMQ instances. If that's explicitly what you want, okay, but otherwise you should have _one context only_.


## Sending and receiving

Since NetMQ is all about the sockets, it is only natural that one would expect to able to send/receive. Since this is such a common area of NetMQ, there is a dedicated documentation page on [receiving and sending](receiving-sending).
Expand All @@ -50,22 +35,21 @@ So let's start with some code, the "Hello world" example (of course).
### Server

:::csharp
using (var context = NetMQContext.Create())
using (var server = context.CreateResponseSocket())
using (var server = new ResponseSocket())
{
server.Bind("tcp://*:5555");

while (true)
{
var message = server.ReceiveString();
var message = server.ReceiveFrameString();

Console.WriteLine("Received {0}", message);

// processing the request
Thread.Sleep(100);

Console.WriteLine("Sending World");
server.Send("World");
server.SendFrame("World");
}
}

Expand All @@ -76,17 +60,16 @@ You can also see that we have zero configuration, we are just sending strings. N
### Client

:::csharp
using (var context = NetMQContext.Create())
using (var client = context.CreateRequestSocket())
using (var client = new RequestSocket())
{
client.Connect("tcp://localhost:5555");

for (int i = 0; i < 10; i++)
{
Console.WriteLine("Sending Hello");
client.Send("Hello");
client.SendFrame("Hello");

var message = client.ReceiveString();
var message = client.ReceiveFrameString();
Console.WriteLine("Received {0}", message);
}
}
Expand All @@ -95,18 +78,14 @@ The client create a socket of type request, connect and start sending messages.

Both the `Send` and `Receive` methods are blocking (by default). For the receive it is simple: if there are no messages the method will block. For sending it is more complicated and depends on the socket type. For request sockets, if the high watermark is reached or no peer is connected the method will block.

You can however call receive or send with the `DontWait` flag to avoid the waiting, make sure to wrap the send or receive with try and catch the `AgainException`, like so:
You can however call `TrySend` and `TryReceive` to avoid the waiting. The operation returns `false` if it would have blocked.

:::csharp
try
{
var message = client.ReceiveString(SendReceiveOptions.DontWait);
string message;
if (client.TryReceiveFrameString(out message))
Console.WriteLine("Received {0}", message);
}
catch (AgainException ex)
{
Console.WriteLine(ex);
}
else
Console.WriteLine("No message received");


## Bind vs Connect
Expand Down
Loading

0 comments on commit a63b9ee

Please sign in to comment.