# roboflex.transport.zmq
Roboflex support for the ZMQ transport.
any node -> ZMQPublisher ==THEINTERNET==> ZMQSubscriber -> any node
See https://zeromq.org/ for details.
Using ZMQ, nodes can connect to other nodes, running in different threads, different processes, or different computers, with a publisher-subscriber pattern. roboflex.transport.zmq supports:
"inproc" transport -> between threads within same process
"ipc" transport -> between processes on same computer
"tcp" transport -> between processes on different computers
## System Dependencies
None! We build libzmq from source...
## pip install
pip install roboflex.transport.zmq
## Import (python)
import roboflex.transport.zmq as rtz
## Build (for c++ projects):
mkdir build && cd build
cmake ..
make
make install
## Run Examples (see [examples](examples))
go to roboflex_transport_zmq/examples
... create and activate some sort of virtual environment
where you installed roboflex.transport.zmq...
python pub_sub_0_py.py
## Nodes:
There are three: `ZMQContext`, `ZMQPublisher`, `ZMQSubscriber`.
To use the ZMQ transport nodes, first you must create a ZMQContext object. This mirrors the design of ZMQ itself.
# all parameters optional
zmq_context = ZMQContext(
num_io_threads = 1,
)
First, know this. "bind addresses" in this world can be three different things. All are strings, but can create different types of queues. These all implement one-to-many publish-subscribe pattern (in fact, it's actually many-to-many).
1. thread-to-thread only queues; "inproc://somename"; the fastest.
2. process-to-process (or thread-to-thread) queues; "ipc://somename"; sort of fast.
3. computer-to-computer (can work anywhere) queues (uses TCP): "tcp://*:5647"; the slowest, but works across the planet.
Then, create a ZMQPublisher:
zmq_pub = ZMQPublisher(
# the ZMQContext object you created
zmq_context,
# what socket to bind to, or what transport to publish on
bind_address = <bind address>,
# or
bind_addresses = [<bind address>],
# optional
# name of the
name = "ZMQPublisher",
# same as 'high-water mark' in zeromq parlance
max_queued_msgs = 1000,
)
#... when a ZMQPublisher receives a message from some upstream node, #it will wire-serialize it, and publish on its transport.
#You can get the bind_addresses:
ba = zmq_pub.bind_addresses
# you can get the high-water mark
hm = zmq_pub.max_queued_msgs
# You can publish a message 'by hand' - same as calling 'receive' on the node.
zmq_pub.publish(some_message)
Then, create one or more ZMQSubscribers, to listen to what you are publishing. ZMQSubscribes are the equivalent of 'sensors' in that the are root nodes, must be started, and start a thread.
zmq_sub = ZMQSubscriber(
# the ZMQContext object you created
zmq_context,
# what socket to bind to, or what transport to subscribe on
connect_address = <bind address>,
# or
connect_addresses = [<bind address>],
# optional
# name of the
name = "ZMQPublisher",
# same as 'high-water mark' in zeromq parlance
max_queued_msgs = 1000,
# how often to yield control on the thread
# You'll probably never change this.
timeout_milliseconds = 10,
)
# you get get values
zmq_sub.connect_addresses
zmq_sub.connect_address
zmq_sub.max_queued_msgs
zmq_sub.timeout_milliseconds
# you MUST start it!
zmq_sub.start()
# you may pull a message 'by hand':
msg_or_none = zmq_sub.pull(
10, # timeout_milliseconds - how long to wait for a message
)
# you may 'produce' messages 'by hand' - this will wait x milliseconds
# for one message, and if it has received one, signals it downstream
zmq_sub.produce(
10, # timeout_milliseconds
)
Raw data
{
"_id": null,
"home_page": "https://github.com/flexrobotics/roboflex_transport_zmq",
"name": "roboflex.transport.zmq",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.6",
"maintainer_email": "",
"keywords": "zmq,zeromq,robotics,middleware,flexbuffers,python,c++,c++20",
"author": "Colin Prepscius",
"author_email": "colinprepscius@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/63/b6/d2a1483f3f921f16d99efbb2b19ad25efd7f8f6dcfca687c87be0330330a/roboflex.transport.zmq-0.1.12.tar.gz",
"platform": null,
"description": "# roboflex.transport.zmq\n\nRoboflex support for the ZMQ transport.\n\n any node -> ZMQPublisher ==THEINTERNET==> ZMQSubscriber -> any node\n\nSee https://zeromq.org/ for details.\n\nUsing ZMQ, nodes can connect to other nodes, running in different threads, different processes, or different computers, with a publisher-subscriber pattern. roboflex.transport.zmq supports:\n\n \"inproc\" transport -> between threads within same process\n \"ipc\" transport -> between processes on same computer\n \"tcp\" transport -> between processes on different computers\n\n\n## System Dependencies\n\n None! We build libzmq from source...\n\n## pip install\n\n pip install roboflex.transport.zmq\n\n## Import (python)\n\n import roboflex.transport.zmq as rtz\n\n## Build (for c++ projects):\n\n mkdir build && cd build\n cmake ..\n make\n make install\n\n## Run Examples (see [examples](examples))\n\n go to roboflex_transport_zmq/examples\n\n ... create and activate some sort of virtual environment\n where you installed roboflex.transport.zmq...\n\n python pub_sub_0_py.py\n\n## Nodes:\n\nThere are three: `ZMQContext`, `ZMQPublisher`, `ZMQSubscriber`.\n\nTo use the ZMQ transport nodes, first you must create a ZMQContext object. This mirrors the design of ZMQ itself.\n\n # all parameters optional\n zmq_context = ZMQContext(\n num_io_threads = 1,\n )\n\nFirst, know this. \"bind addresses\" in this world can be three different things. All are strings, but can create different types of queues. These all implement one-to-many publish-subscribe pattern (in fact, it's actually many-to-many).\n\n 1. thread-to-thread only queues; \"inproc://somename\"; the fastest.\n 2. process-to-process (or thread-to-thread) queues; \"ipc://somename\"; sort of fast.\n 3. computer-to-computer (can work anywhere) queues (uses TCP): \"tcp://*:5647\"; the slowest, but works across the planet.\n\nThen, create a ZMQPublisher:\n\n zmq_pub = ZMQPublisher(\n # the ZMQContext object you created\n zmq_context, \n\n # what socket to bind to, or what transport to publish on\n bind_address = <bind address>,\n # or\n bind_addresses = [<bind address>],\n\n # optional\n \n # name of the\n name = \"ZMQPublisher\",\n\n # same as 'high-water mark' in zeromq parlance\n max_queued_msgs = 1000,\n )\n\n #... when a ZMQPublisher receives a message from some upstream node, #it will wire-serialize it, and publish on its transport.\n\n #You can get the bind_addresses:\n\n ba = zmq_pub.bind_addresses\n\n # you can get the high-water mark\n hm = zmq_pub.max_queued_msgs\n\n # You can publish a message 'by hand' - same as calling 'receive' on the node.\n zmq_pub.publish(some_message)\n\nThen, create one or more ZMQSubscribers, to listen to what you are publishing. ZMQSubscribes are the equivalent of 'sensors' in that the are root nodes, must be started, and start a thread.\n\n zmq_sub = ZMQSubscriber(\n # the ZMQContext object you created\n zmq_context, \n\n # what socket to bind to, or what transport to subscribe on\n connect_address = <bind address>,\n # or\n connect_addresses = [<bind address>],\n\n # optional\n \n # name of the\n name = \"ZMQPublisher\",\n\n # same as 'high-water mark' in zeromq parlance\n max_queued_msgs = 1000,\n\n # how often to yield control on the thread\n # You'll probably never change this.\n timeout_milliseconds = 10,\n )\n\n # you get get values\n zmq_sub.connect_addresses\n zmq_sub.connect_address\n zmq_sub.max_queued_msgs\n zmq_sub.timeout_milliseconds\n\n # you MUST start it!\n zmq_sub.start()\n\n # you may pull a message 'by hand':\n msg_or_none = zmq_sub.pull(\n 10, # timeout_milliseconds - how long to wait for a message\n )\n\n # you may 'produce' messages 'by hand' - this will wait x milliseconds\n # for one message, and if it has received one, signals it downstream\n zmq_sub.produce(\n 10, # timeout_milliseconds\n )\n\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Roboflex Transport ZMQ Library",
"version": "0.1.12",
"project_urls": {
"Homepage": "https://github.com/flexrobotics/roboflex_transport_zmq"
},
"split_keywords": [
"zmq",
"zeromq",
"robotics",
"middleware",
"flexbuffers",
"python",
"c++",
"c++20"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "63b6d2a1483f3f921f16d99efbb2b19ad25efd7f8f6dcfca687c87be0330330a",
"md5": "7e6561557dcdad5ce6e1eb32834868db",
"sha256": "07e3c4ae9d1c0f8a62ddba58c9c3a23c8674c276ff007e0d8a4843264e819f07"
},
"downloads": -1,
"filename": "roboflex.transport.zmq-0.1.12.tar.gz",
"has_sig": false,
"md5_digest": "7e6561557dcdad5ce6e1eb32834868db",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6",
"size": 12514,
"upload_time": "2023-12-05T23:30:26",
"upload_time_iso_8601": "2023-12-05T23:30:26.141011Z",
"url": "https://files.pythonhosted.org/packages/63/b6/d2a1483f3f921f16d99efbb2b19ad25efd7f8f6dcfca687c87be0330330a/roboflex.transport.zmq-0.1.12.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-12-05 23:30:26",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "flexrobotics",
"github_project": "roboflex_transport_zmq",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "roboflex.transport.zmq"
}