jeffbass / imagezmq

A set of Python classes that transport OpenCV images from one computer to another using PyZMQ messaging.
MIT License
1.01k stars 160 forks source link

send message to client from server #11

Closed julio16101 closed 4 years ago

julio16101 commented 5 years ago

Hello again. Following their examples, we see that the client (raspberry) sends to the server (mac) two data, the name of the client and the video frame, but now my question is: is it possible to send a response to the client? for example, I would like to send a response "restart" to the client and be able to perform a restart to the raspberry, in a part of the code I see that the server returns an "ok" to the client, but I did not understand how to recover that message. +

Thank you

jeffbass commented 5 years ago

The imagezmq library uses the imagezmq Request-Reply (REQ-REP) pattern of ZMQ. That pattern requires a specific sequence for every communication between client and server:

# ImageSender Client sends (text, image) pair message
#                 # ImageHub Server sends b'OK' or some other message
# ImageSender Client sends (text, image) pair message
#                 # ImageHub Server sends b'OK' or some other message

...etc. This pattern repeats forever. The "send_reply" is required every time in the REQ-REP messaging sequence. The server can send any message; it does not have to send only the message b'OK'. In my evolving versions of imagehub, the ImageHub Server sends messages such as b'Restart' to restart the ImageSender Client when changing the imagenode client. You can read more about the ZMQ Request-Reply pattern here: http://zguide.zeromq.org/page:all#Ask-and-Ye-Shall-Receive.

My test programs do not bother to recover the "OK" message. To capture the reply message you would just change the send statement to add a variable to receive the reply, like this (see the use of "reply" in the last 2 lines):

# this is the send images loop from test_2_rpi_send_images.py program
rpi_name = socket.gethostname()  # send RPi hostname with each image
picam = VideoStream(usePiCamera=True).start()
time.sleep(2.0)  # allow camera sensor to warm up
while True:  # send images as stream until Ctrl-C
    image = picam.read()
    reply = sender.send_image(rpi_name, image)  # reply holds the return message
    # if reply is ... then ... do something

Hope this helps!

julio16101 commented 5 years ago

Thanks for your response, it is very helpful.

I have another doubt, although not in this same thread, using his library was a great help to transmit video locally to a local server, and in a fast and efficient way, but in addition to that, I must apply techniques such as detection and facial recognition, Due to the high computational cost these processes will not be done locally, but in a server in the cloud, seeing other comments I see that imagezmq is not compatible with flask or django since they occupy different ports, although I could use the imagezmq library to receive the video of the local servers in the cloud, although this is "correct" or could be considered a good practice ?.

also, what do you recommend to be able to send the video in real time to a server in the cloud for the aforementioned processing? talking about the video in real time are many frames.

Thank you.

jeffbass commented 5 years ago

I have not transmitted frames or video to the cloud. It might be possible, but I have no experience with it. ZMQ and imagezmq (which calls ZMQ) can transmit to a TCP/IP and port combination whether that is local or not. But I don't know how you would specify a fixed IP address and a port for a Cloud based server. I suggest you try searches of StackExchange and StackOverflow for questions about using ZMQ with cloud servers. Good luck!

julio16101 commented 4 years ago

I have set up a virtual machine in azure with the zmq server and the video transmission is good, even better than using a web server like flask. Thank you

jeffbass commented 4 years ago

Your welcome! So glad it worked.