Network Connected
Development with ZeroMQ
1
June 13, 2019
About ICS
2
Delivering Smart Devices for a Connected World
● Founded in 1987
● Largest source of independent Qt expertise in North America
● Trusted Qt Service Partner since 2002
● Exclusive Open Enrollment Training Partner in North America
● Provides integrated custom software development and user experience
(UX) design
● Embedded, touchscreen, mobile and desktop applications
● HQ in Waltham, MA with offices in California, Canada, Europe
3
In today’s world everything is communicating, exchanging
messages of some form.
What to use as communication platform is an important choice
that will determine the architecture of your application.
From simple two way communication to complex multi node
architectures, 0MQ helps in providing a safe, fast and reliable
communication medium.
Introduction
4
1. What is 0MQ?
2. Why 0MQ?
3. Universal nature of 0MQ
4. 0MQ patterns overview
5. REQ-REP pattern
6. PUB-SUB pattern
7. Router-Dealer pattern
8. 0MQ and Qt
9. 0MQ and alternatives
10. References
11. Advanced patterns
Agenda
5
ZeroMQ is an embeddable networking library.
It gives you sockets that carry atomic messages across
various transports like in-process, inter-process, TCP, and
multicast.
It has a score of language APIs and runs on most operating
systems
It is open source under LGPLv3 license
What is 0MQ
6
● It handles I/O asynchronously. Concurrent 0MQ applications need no locks or
semaphores
● Component come and go dynamically, 0MQ reconnects them automatically
● It queues message automatically when needed and does it intelligently
● It has way dealing with over full queues ( “high water mark” )
● Supports multiple transports - TCP, multi-cast, in-process, interprocess
● It handles slow/blocked readers safely depending on messaging pattern
● It lets you to route messages using variety of patterns
● It lets you to create proxies to queue, forward and capture messages with single
call
● It delivers messages exactly as it sent
● It does not impose any format on messages
Why 0MQ
7
● Written on C++
● Community officially supports CZMQ(C/C++),
JeroMQ(Java), NetMQ(.Net)
● Supports every modern language and platform
● Works in any architecture - centralized or distributed, small
or large
● 40+ language bindings - Ada, Fortran-77, LabView,
Node.js, Python, Swift, Obj-C, Ruby, Smalltalk, Tcl, etc
Universal Nature of 0MQ
8
● Dealer
● Router
● Push
● Pull
● Pair
0MQ offers sockets intended as “building blocks” that we can combine
in nearly any combination to match our architectural needs.
● Request
● Reply
● Publisher
● Subscriber
● XPub
● XSub
0MQ Patterns Overview
9
● Synchronous
● Basic send-receive
capabilities
● REQ: send then recv
● REP: recv then send
REQ - REP Pattern
10
REQ - REP Example
11
0MQ - MacOS/iOS/Swift
12
● Asynchronous
● SUB will lose initial messages
after connection - slow joiner
syndrome
● SUB needs to register to a channel to
start receiving
● SUB can connect to multiple PUB
● PUB has the queue
PUB - SUB pattern
13
#
# Weather update server
# Binds PUB socket to tcp://*:5556
# Publishes random weather updates
#
import zmq
from random import randrange
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:5556")
while True:
zipcode = randrange(1, 100000)
temperature = randrange(-80, 135)
relhumidity = randrange(10, 60)
socket.send_string("%i %i %i" %
(zipcode, temperature, relhumidity))
#
# Weather update client
# Connects SUB socket to tcp://localhost:5556
#
import sys
import zmq
# Socket to talk to server
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect("tcp://localhost:5556")
# Subscribe to zipcode, default is NYC, 10001
zip_filter = sys.argv[1] if len(sys.argv) > 1 else "10001"
# Python 2 - ascii bytes to unicode str
if isinstance(zip_filter, bytes):
zip_filter = zip_filter.decode('ascii')
socket.setsockopt_string(zmq.SUBSCRIBE, zip_filter)
# Process 5 updates
total_temp = 0
for update_nbr in range(5):
string = socket.recv_string()
zipcode, temperature, relhumidity = string.split()
total_temp += int(temperature)
print("Average temperature for zipcode '%s' was %dF" % (
zip_filter, total_temp / (update_nbr+1))
)
PUB - SUB Example
14
● Asynchronous
● Dealer is an asynchronous REQ
● Router is an asynchronous REP
● Automatic routing handling
● Can be automatically proxied
together
● Use Extended Envelope
Dealer - Router Pattern
15
Building a basic file transfer protocol using only a dealer and a router
● Option #1:
Dealer sends request for a file, Router sends the file serialized
● Option #2:
Dealer sends request for a chunk of a file, Router sends that chunk -
repeat
● Option #3:
Dealer asks for the max amount of chunks that can handle, Router
sends multiple chunks - repeat
Dealer - Router Pattern
16
Building a basic file transfer protocol using only a dealer and a router
Option #1:
Dealer sends request for a file, Router sends the file serialized
Issues:
● Running out of memory
● Router side to load the entire file
● Dealer side to receive the entire file
Solution:
Set a high water mark on the dealer to avoid to run out of memory
Dealer - Router Pattern
17
Building a basic file transfer protocol using only a dealer and a router
Option #2:
Dealer sends request for a chunk of a file, Router sends that chunk -
repeat
Issues:
Slow - too much overhead
Solution:
Reduce overhead :-)
Dealer - Router Pattern
18
Building a basic file transfer protocol using only a dealer and a router
Option #3:
Dealer asks for the max amount of chunks that can handle, Router
sends multiple chunks - repeat
Pro:
No need for HWM
No need for delays/sleep
Fully recoverable
Fast
Dealer - Router Pattern
19
● No official binding - there were various attempt but none is
maintained AFAIK.
● Use QTimers to handle polling
● Set QTimer::timeout and poll::timeout to reasonable values for
your application
● Move your class out of the UI thread
● Isolate 0MQ logic from app logic
0MQ and Qt
20
● nanomsg and nng - https://nanomsg.github.io/nng/
● Developed by Garrett D’Amore and Martin Sustrik of 0MQ
● MIT license vs LGPL3
● Pluggable transport
● Written on C (0MQ is C++)
● POSIX compliant
0MQ and Alternatives
21
ZGuide: http://zguide.zeromq.org
FileMQ: https://github.com/zeromq/filemq
cppzmq: https://github.com/zeromq/cppzmq
libzmq: https://github.com/zeromq/libzmq
ICS Articles: https://www.ics.com/blog/build-high-performance-messaging-service-qt-and-ios
https://www.ics.com/blog/lets-build-zeromq-library
References
22
Advanced Patterns - Pipeline
PUSH-PULL:
● PUSH sockets publish “tasks”
● PULL sockets reads “tasks”
● PUSH sockets distribute the loads between
PULL sockets
● PULL reads fairly between multiple PUSH
23
Simple envelope and extended envelope

Network-Connected Development with ZeroMQ

  • 1.
    Network Connected Development withZeroMQ 1 June 13, 2019
  • 2.
    About ICS 2 Delivering SmartDevices for a Connected World ● Founded in 1987 ● Largest source of independent Qt expertise in North America ● Trusted Qt Service Partner since 2002 ● Exclusive Open Enrollment Training Partner in North America ● Provides integrated custom software development and user experience (UX) design ● Embedded, touchscreen, mobile and desktop applications ● HQ in Waltham, MA with offices in California, Canada, Europe
  • 3.
    3 In today’s worldeverything is communicating, exchanging messages of some form. What to use as communication platform is an important choice that will determine the architecture of your application. From simple two way communication to complex multi node architectures, 0MQ helps in providing a safe, fast and reliable communication medium. Introduction
  • 4.
    4 1. What is0MQ? 2. Why 0MQ? 3. Universal nature of 0MQ 4. 0MQ patterns overview 5. REQ-REP pattern 6. PUB-SUB pattern 7. Router-Dealer pattern 8. 0MQ and Qt 9. 0MQ and alternatives 10. References 11. Advanced patterns Agenda
  • 5.
    5 ZeroMQ is anembeddable networking library. It gives you sockets that carry atomic messages across various transports like in-process, inter-process, TCP, and multicast. It has a score of language APIs and runs on most operating systems It is open source under LGPLv3 license What is 0MQ
  • 6.
    6 ● It handlesI/O asynchronously. Concurrent 0MQ applications need no locks or semaphores ● Component come and go dynamically, 0MQ reconnects them automatically ● It queues message automatically when needed and does it intelligently ● It has way dealing with over full queues ( “high water mark” ) ● Supports multiple transports - TCP, multi-cast, in-process, interprocess ● It handles slow/blocked readers safely depending on messaging pattern ● It lets you to route messages using variety of patterns ● It lets you to create proxies to queue, forward and capture messages with single call ● It delivers messages exactly as it sent ● It does not impose any format on messages Why 0MQ
  • 7.
    7 ● Written onC++ ● Community officially supports CZMQ(C/C++), JeroMQ(Java), NetMQ(.Net) ● Supports every modern language and platform ● Works in any architecture - centralized or distributed, small or large ● 40+ language bindings - Ada, Fortran-77, LabView, Node.js, Python, Swift, Obj-C, Ruby, Smalltalk, Tcl, etc Universal Nature of 0MQ
  • 8.
    8 ● Dealer ● Router ●Push ● Pull ● Pair 0MQ offers sockets intended as “building blocks” that we can combine in nearly any combination to match our architectural needs. ● Request ● Reply ● Publisher ● Subscriber ● XPub ● XSub 0MQ Patterns Overview
  • 9.
    9 ● Synchronous ● Basicsend-receive capabilities ● REQ: send then recv ● REP: recv then send REQ - REP Pattern
  • 10.
    10 REQ - REPExample
  • 11.
  • 12.
    12 ● Asynchronous ● SUBwill lose initial messages after connection - slow joiner syndrome ● SUB needs to register to a channel to start receiving ● SUB can connect to multiple PUB ● PUB has the queue PUB - SUB pattern
  • 13.
    13 # # Weather updateserver # Binds PUB socket to tcp://*:5556 # Publishes random weather updates # import zmq from random import randrange context = zmq.Context() socket = context.socket(zmq.PUB) socket.bind("tcp://*:5556") while True: zipcode = randrange(1, 100000) temperature = randrange(-80, 135) relhumidity = randrange(10, 60) socket.send_string("%i %i %i" % (zipcode, temperature, relhumidity)) # # Weather update client # Connects SUB socket to tcp://localhost:5556 # import sys import zmq # Socket to talk to server context = zmq.Context() socket = context.socket(zmq.SUB) socket.connect("tcp://localhost:5556") # Subscribe to zipcode, default is NYC, 10001 zip_filter = sys.argv[1] if len(sys.argv) > 1 else "10001" # Python 2 - ascii bytes to unicode str if isinstance(zip_filter, bytes): zip_filter = zip_filter.decode('ascii') socket.setsockopt_string(zmq.SUBSCRIBE, zip_filter) # Process 5 updates total_temp = 0 for update_nbr in range(5): string = socket.recv_string() zipcode, temperature, relhumidity = string.split() total_temp += int(temperature) print("Average temperature for zipcode '%s' was %dF" % ( zip_filter, total_temp / (update_nbr+1)) ) PUB - SUB Example
  • 14.
    14 ● Asynchronous ● Dealeris an asynchronous REQ ● Router is an asynchronous REP ● Automatic routing handling ● Can be automatically proxied together ● Use Extended Envelope Dealer - Router Pattern
  • 15.
    15 Building a basicfile transfer protocol using only a dealer and a router ● Option #1: Dealer sends request for a file, Router sends the file serialized ● Option #2: Dealer sends request for a chunk of a file, Router sends that chunk - repeat ● Option #3: Dealer asks for the max amount of chunks that can handle, Router sends multiple chunks - repeat Dealer - Router Pattern
  • 16.
    16 Building a basicfile transfer protocol using only a dealer and a router Option #1: Dealer sends request for a file, Router sends the file serialized Issues: ● Running out of memory ● Router side to load the entire file ● Dealer side to receive the entire file Solution: Set a high water mark on the dealer to avoid to run out of memory Dealer - Router Pattern
  • 17.
    17 Building a basicfile transfer protocol using only a dealer and a router Option #2: Dealer sends request for a chunk of a file, Router sends that chunk - repeat Issues: Slow - too much overhead Solution: Reduce overhead :-) Dealer - Router Pattern
  • 18.
    18 Building a basicfile transfer protocol using only a dealer and a router Option #3: Dealer asks for the max amount of chunks that can handle, Router sends multiple chunks - repeat Pro: No need for HWM No need for delays/sleep Fully recoverable Fast Dealer - Router Pattern
  • 19.
    19 ● No officialbinding - there were various attempt but none is maintained AFAIK. ● Use QTimers to handle polling ● Set QTimer::timeout and poll::timeout to reasonable values for your application ● Move your class out of the UI thread ● Isolate 0MQ logic from app logic 0MQ and Qt
  • 20.
    20 ● nanomsg andnng - https://nanomsg.github.io/nng/ ● Developed by Garrett D’Amore and Martin Sustrik of 0MQ ● MIT license vs LGPL3 ● Pluggable transport ● Written on C (0MQ is C++) ● POSIX compliant 0MQ and Alternatives
  • 21.
    21 ZGuide: http://zguide.zeromq.org FileMQ: https://github.com/zeromq/filemq cppzmq:https://github.com/zeromq/cppzmq libzmq: https://github.com/zeromq/libzmq ICS Articles: https://www.ics.com/blog/build-high-performance-messaging-service-qt-and-ios https://www.ics.com/blog/lets-build-zeromq-library References
  • 22.
    22 Advanced Patterns -Pipeline PUSH-PULL: ● PUSH sockets publish “tasks” ● PULL sockets reads “tasks” ● PUSH sockets distribute the loads between PULL sockets ● PULL reads fairly between multiple PUSH
  • 23.
    23 Simple envelope andextended envelope