Send NULL message in PyZMQ
python, pyzmq, zeromq
Solution
First point: `zmq.NULL` is the `ZMQ_NULL` constant, for use in zeromq's security mechanism. For example:
socket.mechanism = zmq.NULL # or zmq.PLAIN or zmq.CURVE
It is not the `NULL` special C constant.
To send an empty message, simply send an empty bytestring:
socket.send(b'')
The second point is that you need to send the empty frame as a separate message, which you are not doing. Here is a working example:
def http_hello_world():
ctx = zmq.Context()
sock = ctx.socket(zmq.ROUTER)
sock.router_raw = True
sock.bind("tcp://*:8080")
while True:
id_bytes, request = sock.recv_multipart()
print("id: %r" % id_bytes)
print("request:", request.decode('utf8'))
if b'/close' in request:
return
# send the body of the response
sock.send_multipart([
id_bytes,
b"""HTTP/1.0 200 OK
Content-Type: text/plain
Hello, world!
"""
])
# send an empty message to finish the response
sock.send_multipart([
id_bytes,
b''
])
By the way, a comment in Github entry shows that it may not close the connection to the client even in C. How can I ask the remote client to close its connection (in Python) ?
I think, as long as you send the empty frame to terminate the message, connections should be closed.
Problem
I'm trying to translate the following example HTTP server based on 0MQ written in C seen here: Hintjens' blog into Python. ``` def test_http_socket(): ctx = zmq.Context() sock = ctx.socket(zmq.ROUTER) sock.setsockopt(zmq.ROUTER_RAW, 1) sock.bind("tcp://*:8080") while True: id_bytes = sock.recv() print("id=",id_bytes) request = sock.recv() print("request=",request) if b'/close' in request: return sock.send(id_bytes, zmq.SNDMORE) sock.send(b"""HTTP/1.0 200 OK Content-Type: text/plain Hello, world !""") sock.send(zmq.NULL) ``` The problem is on the next line, where I try to translate the C expression ``` zmq_send (router, NULL, 0, 0); ``` In Python I have the following stack trace: ``` Traceback (most recent call last): File "<pyshell#96>", line 1, in <module> test_http_socket() File "<pyshell#95>", line 18, in test_http_socket sock.send(zmq.NULL) File "socket.pyx", line 565, in zmq.backend.cython.socket.Socket.send (zmq\backend\cython\socket.c:5104) File "socket.pyx", line 612, in zmq.backend.cython.socket.Socket.send (zmq\backend\cython\socket.c:4868) File "socket.pyx", line 168, in zmq.backend.cython.socket._send_copy (zmq\backend\cython\socket.c:1914) File "buffers.pxd", line 200, in buffers.asbuffer_r (zmq\backend\cython\socket.c:6833) File "buffers.pxd", line 151, in buffers.asbuffer (zmq\backend\cython\socket.c:6270) TypeError: 0 does not provide a buffer interface. ``` In fact, sock.send can only be used to send buffers or messages. Is there a way to use 0MQ's zmq_send in another manner from Python, to send a NULL frame ? By the way, a comment in Github entry shows that it may not close the connection to the client even in C. How can I ask the remote client to close its connection (in Python) ? I'm using libzmq 4.0.1 and PyZMQ 14.0.1 over Python 3.3.2 on Windows 32bits.