Skip to content

Migrating to v4

Drew Noakes edited this page Jun 29, 2016 · 2 revisions

Migration from NetMQ version 3 to 4

NetMQ version 4 introduces some breaking changes for code migrated from version 3. These changes simplify the use of NetMQ, and the migration is not so difficult.

Should I upgrade?

NetMQ version 3 will continue to receive bug fixes, but new features and improvements will be made to version 4 only. We expect most users will benefit from upgrading and encourage doing so.

How to upgrade?

  1. Make sure you take the latest release of the NetMQ 3 family from NuGet.
  2. Address any compiler warnings about usages of obsolete code. The compiler warnings will guide you regarding what changes are required.
  3. Uninstall the NetMQ NuGet package, and install the NetMQ4 package instead.

Changes

Much of the removed code have been marked [Obsolete] for several releases now, so many of the changes shown here are unlikely to apply to your code. Further, any one application is unlikely to depend upon much of the public API of NetMQ. Don't let the length of this list concern you.

For completeness, all API changes are detailed here.

The context

NetMQContext has been removed. Previously you'd create one of these in your application and pass it around. NetMQ now manages this internally, making the API simpler.

Here's a comparison:

// NetMQ version 3
using (var context = NetMQContext.Create())
using (var publisher = context.CreatePublisherSocket())
{
    // ...
}

// NetMQ version 4
using (var publisher = new PublisherSocket())
{
    // ...
}

Note the factory methods for sockets no longer exist. Instead, just call the constructor of the type you want to use.

  • NetMQContext.CreateRequestSocket() πŸ‘‰ new RequestSocket()
  • NetMQContext.CreateResponseSocket() πŸ‘‰ new ResponseSocket()
  • NetMQContext.CreateDealerSocket() πŸ‘‰ new DealerSocket()
  • NetMQContext.CreateRouterSocket() πŸ‘‰ new RouterSocket()
  • NetMQContext.CreateXPublisherSocket() πŸ‘‰ new XPublisherSocket()
  • NetMQContext.CreatePairSocket() πŸ‘‰ new PairSocket()
  • NetMQContext.CreatePushSocket() πŸ‘‰ new PushSocket()
  • NetMQContext.CreatePublisherSocket() πŸ‘‰ new PublisherSocket()
  • NetMQContext.CreatePullSocket() πŸ‘‰ new PullSocket()
  • NetMQContext.CreateSubscriberSocket() πŸ‘‰ new SubscriberSocket()
  • NetMQContext.CreateXSubscriberSocket() πŸ‘‰ new XSubscriberSocket()
  • NetMQContext.CreateStreamSocket() πŸ‘‰ new StreamSocket()
  • NetMQContext.CreateMonitorSocket() πŸ‘‰ new MonitorSocket()

Further, constructors of the following classes no longer receive a context and calls should be updated:

  • NetMQForwarder
  • NetMQBeacon
  • QueueDevice
  • StreamerDevice
  • NetMQMonitor

These factory methods no longer accept context instances:

  • NetMQActor.Create

Poller and Scheduler

The Poller and NetMQScheduler classes have been merged into the new NetMQPoller class.

  • Poller πŸ‘‰ NetMQPoller

Adding and removing objects to poll:

  • Poller.AddSocket πŸ‘‰ NetMQPoller.Add
  • Poller.AddTimer πŸ‘‰ NetMQPoller.Add
  • Poller.AddPollInSocket πŸ‘‰ NetMQPoller.Add
  • Poller.RemoveSocket πŸ‘‰ NetMQPoller.Remove
  • Poller.RemoveTimer πŸ‘‰ NetMQPoller.Remove
  • Poller.RemovePollInSocket πŸ‘‰ NetMQPoller.Remove

Starting and stopping the poller.

  • Poller.PollTillCancelled πŸ‘‰ NetMQPoller.Run
  • Poller.PollTillCancelledNonBlocking πŸ‘‰ NetMQPoller.RunAsync
  • Poller.Cancel πŸ‘‰ NetMQPoller.Stop
  • Poller.CancelNonBlocking πŸ‘‰ NetMQPoller.StopAsync

Scheduling for the TPL:

  • NetMQScheduler πŸ‘‰ NetMQPoller

By changing the Add* names to all be the same as simply Add, and by implementing IEnumerable, NetMQPoller now supports collection initialiser syntax:

new NetMQPoller { publisher, subscriber, timer, tcpSocket }

NetMQPoller now implements ISynchronizeInvoke (and continues extending TaskScheduler), so it can be used to get schedule and synchronise work on the poller's thread from both the TPL and earlier BCL APIs.

Receiving

Receiving a single frame using Msg:

  • IReceivingSocket.Receive(ref Msg, SendReceiveOptions) πŸ‘‰
    • Receive(ref Msg)
    • TryReceive(ref Msg, TimeSpan) : bool

Receiving a single frame as a byte[]:

  • IReceivingSocket.Receive() : byte[]
  • IReceivingSocket.Receive(out bool) : byte[]
  • IReceivingSocket.Receive(bool, out bool) : byte[]
  • IReceivingSocket.Receive(SendReceiveOptions) : byte[]
  • IReceivingSocket.Receive(SendReceiveOptions, out bool) : byte[]
  • IReceivingSocket.Receive(TimeSpan) : byte[] πŸ‘‰
    • ReceiveFrameBytes(): byte[]
    • ReceiveFrameBytes(out bool): byte[]
    • TryReceiveFrameBytes(out byte[]) : bool
    • TryReceiveFrameBytes(out byte[], out bool) : bool
    • TryReceiveFrameBytes(TimeSpan, out byte[]) : bool
    • TryReceiveFrameBytes(TimeSpan, out byte[], out bool) : bool

Receiving an entire multipart message as List<byte[]>:

  • IReceivingSocket.ReceiveMessages() : List<byte[]>(int)
  • IReceivingSocket.ReceiveAll() : List<byte[]>(int) πŸ‘‰
    • IReceivingSocket.ReceiveMultipartBytes(int) : List<byte[]>
    • IReceivingSocket.ReceiveMultipartBytes(ref List<byte[]>, int): void
    • IReceivingSocket.TryReceiveMultipartBytes(ref List<byte[]>, int): bool
    • IReceivingSocket.TryReceiveMultipartBytes(TimeSpan, ref List<byte[]>, int): bool

Receiving a single frame as a string:

  • IReceivingSocket.ReceiveString() : string
  • IReceivingSocket.ReceiveString(SendReceiveOptions) : string
  • IReceivingSocket.ReceiveString(SendReceiveOptions, out bool) : string
  • IReceivingSocket.ReceiveString(Encoding) : string
  • IReceivingSocket.ReceiveString(Encoding, SendReceiveOptions) : string
  • IReceivingSocket.ReceiveString(Encoding, SendReceiveOptions, out bool) : string
  • IReceivingSocket.ReceiveString(out bool) : string
  • IReceivingSocket.ReceiveString(bool, out bool) : string
  • IReceivingSocket.ReceiveString(TimeSpan) : string
  • IReceivingSocket.ReceiveString(Encoding, out bool) : string
  • IReceivingSocket.ReceiveString(Encoding, bool, out bool) : string
  • IReceivingSocket.ReceiveString(Encoding, TimeSpan) : string πŸ‘‰
    • IReceivingSocket.ReceiveFrameString() : string
    • IReceivingSocket.ReceiveFrameString(out bool) : string
    • IReceivingSocket.ReceiveFrameString(Encoding) : string
    • IReceivingSocket.ReceiveFrameString(Encoding, out bool) : string
    • IReceivingSocket.TryReceiveFrameString(out string) : bool
    • IReceivingSocket.TryReceiveFrameString(out string, out bool) : bool
    • IReceivingSocket.TryReceiveFrameString(Encoding, out string) : bool
    • IReceivingSocket.TryReceiveFrameString(Encoding, out string, out bool) : bool
    • IReceivingSocket.TryReceiveFrameString(TimeSpan, out string) : bool
    • IReceivingSocket.TryReceiveFrameString(TimeSpan, out string, out bool) : bool
    • IReceivingSocket.TryReceiveFrameString(TimeSpan, Encoding, out string) : bool
    • IReceivingSocket.TryReceiveFrameString(TimeSpan, Encoding, out string, out bool) : bool

Receiving an entire multipart message as List<string>:

  • IReceivingSocket.ReceiveStringMessages(int) : List<string>
  • IReceivingSocket.ReceiveStringMessages(Encoding, int) : List<string>
  • IReceivingSocket.ReceiveAllString() : List<string> πŸ‘‰
    • IReceivingSocket.ReceiveMultipartStrings() : List<string>
    • IReceivingSocket.ReceiveMultipartStrings(out bool) : List<string>
    • IReceivingSocket.TryReceiveMultipartStrings(ref List<string>, int) : bool
    • IReceivingSocket.TryReceiveMultipartStrings(Encoding, ref List<string>, int) : bool
    • IReceivingSocket.TryReceiveMultipartStrings(TimeSpan, ref List<string>, int) : bool
    • IReceivingSocket.TryReceiveMultipartStrings(TimeSpan, Encoding, ref List<string>, int) : bool

Receiving an entire multipart message as NetMQMessage:

  • IReceivingSocket.ReceiveMessage(bool) : NetMQMessage
  • IReceivingSocket.ReceiveMessage(NetMQMessage, bool) : void
  • IReceivingSocket.ReceiveMessage(TimeSpan) : NetMQMessage πŸ‘‰
    • IReceivingSocket.ReceiveMultipartMessage(int) : NetMQMessage
    • IReceivingSocket.TryReceiveMultipartMessage(ref NetMQMessage, int): bool
    • IReceivingSocket.TryReceiveMultipartMessage(TimeSpan ref NetMQMessage, int): bool

Receiving a signal:

  • IReceivingSocket.WaitForSignal() : bool πŸ‘‰
    • IReceivingSocket.ReceiveSignal(): bool
    • IReceivingSocket.TryReceiveSignal(out bool): bool
    • IReceivingSocket.TryReceiveSignal(TimeSpan, out bool): bool

The ability to skip a frame has been added:

  • IReceivingSocket.SkipFrame(): bool
  • IReceivingSocket.SkipFrame(out bool): bool
  • IReceivingSocket.TrySkipFrame(): bool
  • IReceivingSocket.TrySkipFrame(out bool): bool
  • IReceivingSocket.TrySkipFrame(TimeSpan): bool
  • IReceivingSocket.TrySkipFrame(TimeSpan, out bool): bool

As well as the ability to skip entire multipart messages, or the remainder of the current message when partially received:

  • IReceivingSocket.SkipMultipartMessage(): bool

  • IReceivingSocket.TrySkipMultipartMessage(): bool

  • IReceivingSocket.TrySkipMultipartMessage(TimeSpan): bool

  • NetMQSocketEventArgs.ReceiveReady πŸ‘‰ NetMQSocketEventArgs.IsReadyToReceive

Sending

  • IOutgoingSocket.Send(ref Msg, SendReceiveOptions) πŸ‘‰

    • Send(ref Msg, bool)
    • TrySend(ref Msg, TimeSpan, bool)
  • IOutgoingSocket.Send(byte[], int, SendReceiveOptions)

  • IOutgoingSocket.Send(byte[], int, bool, bool)

  • IOutgoingSocket.Send(byte[])

  • IOutgoingSocket.SendMore(byte[], bool)

  • IOutgoingSocket.SendMore(byte[], int, bool) πŸ‘‰

    • SendFrame(byte[], bool)
    • SendFrame(byte[], int, bool)
    • SendMoreFrame(byte[])
    • SendMoreFrame(byte[], int)
    • TrySendFrame(TimeSpan, byte[], bool)
    • TrySendFrame(TimeSpan, byte[], int, bool)
    • TrySendFrame(byte[], bool)
    • TrySendFrame(byte[], int, bool)
  • IOutgoingSocket.Send(string, bool, bool)

  • IOutgoingSocket.Send(string, Encoding, SendReceiveOptions)

  • IOutgoingSocket.Send(string, Encoding, bool, bool)

  • IOutgoingSocket.SendMore(string, bool)

  • IOutgoingSocket.SendMore(string, Encoding, bool) πŸ‘‰

    • SendFrame(string, bool)
    • SendMoreFrame(string)
    • TrySendFrame(TimeSpan, string, bool)
    • TrySendFrame(string, bool)
  • IOutgoingSocket.SendMessage(NetMQMessage, bool) πŸ‘‰

    • SendMultipartMessage(NetMQMessage)
    • TrySendMultipartMessage(NetMQMessage)
    • TrySendMultipartMessage(TimeSpan, NetMQMessage)
  • NetMQSocketEventArgs.SendReady πŸ‘‰ NetMQSocketEventArgs.IsReadyToSend

Subscribe / Unsubscribe

The Subscribe and Unsubscribe methods have been pushed down the class hierarchy from NetMQSocket to only those subclasses to which subscription applies (SubscriberSocket and XSubscriberSocket). This shouldn't affect any correct code, but is mentioned here for completeness.

Socket Options

Some unused socket options were removed:

  • ReceiveTimeout (use overloads of TryReceive that accept a TimeSpan)
  • SendTimeout (use overloads of TrySend that accept a TimeSpan)
  • TcpAcceptFilter
  • TcpKeepaliveCnt
  • CopyMessages
  • ReceivevBuffer πŸ‘‰ ReceiveBuffer (typo)
  • GetLastEndpoint πŸ‘‰ LastEndpoint

Exceptions

  • ErrorPollingException was unused and has been removed
  • AgainException is no longer used as send/receive methods use the Try* pattern and return false in case the operation would block

Error codes

Unused members of the ErrorCode enum have been removed.

  • ErrorCode.InProgres πŸ‘‰ ErrorCode.InProgress (typo)
  • ErrorCode.ENOENT πŸ‘‰ ErrorCode.EndpointNotFound
  • ErrorCode.EACCESS πŸ‘‰ ErrorCode.AccessDenied
  • ErrorCode.EFAULT πŸ‘‰ ErrorCode.Fault
  • ErrorCode.EINV πŸ‘‰ ErrorCode.Invalid
  • ErrorCode.EAGAIN πŸ‘‰ ErrorCode.TryAgain
  • ErrorCode.EINPROGRESS πŸ‘‰ ErrorCode.InProgress
  • ErrorCode.EPROTONOSUPPORT πŸ‘‰ ProtocolNotSupported.
  • ErrorCode.ENOTSUP ❎
  • ErrorCode.EADDRINUSE πŸ‘‰ ErrorCode.AddressAlreadyInUse
  • ErrorCode.EADDRNOTAVAIL πŸ‘‰ ErrorCode.AddressNotAvailable
  • ErrorCode.ENETDOWN πŸ‘‰ ErrorCode.NetworkDown
  • ErrorCode.ENOBUFS πŸ‘‰ ErrorCode.NoBufferSpaceAvailable
  • ErrorCode.EISCONN ❎
  • ErrorCode.EINTR ❎
  • ErrorCode.ENOTCONN πŸ‘‰ ErrorCode.NotConnected
  • ErrorCode.ECONNREFUSED πŸ‘‰ ErrorCode.ConnectionRefused
  • ErrorCode.EHOSTUNREACH πŸ‘‰ ErrorCode.HostUnreachable
  • ErrorCode.ZMQ_HAUSNUMERO πŸ‘‰ ErrorCode.BaseErrorNumber
  • ErrorCode.EMSGSIZE πŸ‘‰ ErrorCode.MessageSize
  • ErrorCode.EAFNOSUPPORT πŸ‘‰ ErrorCode.AddressFamilyNotSupported
  • ErrorCode.ENETUNREACH πŸ‘‰ ErrorCode.NetworkUnreachable
  • ErrorCode.ECONNABORTED πŸ‘‰ ErrorCode.ConnectionAborted
  • ErrorCode.ECONNRESET πŸ‘‰ ErrorCode.ConnectionReset
  • ErrorCode.ETIMEDOUT πŸ‘‰ ErrorCode.TimedOut
  • ErrorCode.ENETRESET πŸ‘‰ ErrorCode.NetworkReset
  • ErrorCode.EFSM πŸ‘‰ ErrorCode.FiniteStateMachine
  • ErrorCode.ENOCOMPATPROTO ❎
  • ErrorCode.ETERM πŸ‘‰ ErrorCode.ContextTerminated
  • ErrorCode.EMTHREAD πŸ‘‰ ErrorCode.EmptyThread
  • ErrorCode.EIOEXC ❎
  • ErrorCode.ESOCKET ❎
  • ErrorCode.EMFILE πŸ‘‰ ErrorCode.TooManyOpenSockets

Miscellaneous

The following items have been obsolete for a long time and their use is very unlikely if you observe compiler warnings. However they are listed here for completeness.

  • Blob πŸ‘‰ NetMQFrame
  • Actor<T> πŸ‘‰ NetMQActor (non-generic)
  • IShimHandler<T> πŸ‘‰ IShimHandler (non-generic)
  • ActorKnownMessages.END_PIPE πŸ‘‰ NetMQActor.EndShimMessage
  • enum MsgType.Invalid πŸ‘‰ MsgType.Uninitialised
  • MsgType.Check() πŸ‘‰ MsgType.IsInitialised
  • SocketEvent πŸ‘‰ SocketEvents