|
|
|
@ -3,12 +3,33 @@
|
|
|
|
|
# Distributed under the MIT software license, see the accompanying
|
|
|
|
|
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
|
|
|
|
|
# A blocking example using python 2.7 can be obtained from the git history:
|
|
|
|
|
# https://github.com/bitcoin/bitcoin/blob/37a7fe9e440b83e2364d5498931253937abe9294/contrib/zmq/zmq_sub.py
|
|
|
|
|
"""
|
|
|
|
|
ZMQ example using python3's asyncio
|
|
|
|
|
|
|
|
|
|
Bitcoin should be started with the command line arguments:
|
|
|
|
|
bitcoind -testnet -daemon \
|
|
|
|
|
-zmqpubhashblock=tcp://127.0.0.1:28332 \
|
|
|
|
|
-zmqpubrawtx=tcp://127.0.0.1:28332 \
|
|
|
|
|
-zmqpubhashtx=tcp://127.0.0.1:28332 \
|
|
|
|
|
-zmqpubhashblock=tcp://127.0.0.1:28332
|
|
|
|
|
|
|
|
|
|
We use the asyncio library here. `self.handle()` installs itself as a
|
|
|
|
|
future at the end of the function. Since it never returns with the event
|
|
|
|
|
loop having an empty stack of futures, this creates an infinite loop. An
|
|
|
|
|
alternative is to wrap the contents of `handle` inside `while True`.
|
|
|
|
|
|
|
|
|
|
The `@asyncio.coroutine` decorator and the `yield from` syntax found here
|
|
|
|
|
was introduced in python 3.4 and has been deprecated in favor of the `async`
|
|
|
|
|
and `await` keywords respectively.
|
|
|
|
|
|
|
|
|
|
A blocking example using python 2.7 can be obtained from the git history:
|
|
|
|
|
https://github.com/bitcoin/bitcoin/blob/37a7fe9e440b83e2364d5498931253937abe9294/contrib/zmq/zmq_sub.py
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import array
|
|
|
|
|
import binascii
|
|
|
|
|
import asyncio, zmq, zmq.asyncio
|
|
|
|
|
import asyncio
|
|
|
|
|
import zmq
|
|
|
|
|
import zmq.asyncio
|
|
|
|
|
import signal
|
|
|
|
|
import struct
|
|
|
|
|
import sys
|
|
|
|
@ -56,7 +77,8 @@ class ZMQHandler():
|
|
|
|
|
asyncio.ensure_future(self.handle())
|
|
|
|
|
|
|
|
|
|
def start(self):
|
|
|
|
|
asyncio.ensure_future(self.handle())
|
|
|
|
|
self.loop.add_signal_handler(signal.SIGINT, self.stop)
|
|
|
|
|
self.loop.create_task(self.handle())
|
|
|
|
|
self.loop.run_forever()
|
|
|
|
|
|
|
|
|
|
def stop(self):
|
|
|
|
@ -64,8 +86,4 @@ class ZMQHandler():
|
|
|
|
|
self.zmqContext.destroy()
|
|
|
|
|
|
|
|
|
|
daemon = ZMQHandler()
|
|
|
|
|
def signal_handler(num, frame):
|
|
|
|
|
daemon.stop()
|
|
|
|
|
exit(0)
|
|
|
|
|
signal.signal(signal.SIGINT, signal_handler)
|
|
|
|
|
daemon.start()
|
|
|
|
|