Skip to content

Multi-Servers Mode for NetGear API

NetGear's Multi-Servers Mode
NetGear's Multi-Servers Mode

Overview

In Multi-Servers Mode, NetGear API robustly handles Multiple Servers at once, thereby providing seamless access to frames and unidirectional data transfer across multiple Publishers/Servers in the network at the same time. Each new server connects to a single client can be identified by its unique port address on the network.

The supported patterns for this mode are Publish/Subscribe (zmq.PUB/zmq.SUB) and Request/Reply(zmq.REQ/zmq.REP) and can be easily activated in NetGear API through multiserver_mode attribute of its options dictionary parameter during initialization.

 

Important Information regarding Multi-Servers Mode

  • A unique PORT address MUST be assigned to each Server on the network using its port parameter.

  • A list/tuple of PORT addresses of all unique Servers MUST be assigned at Client's end using its port parameter for a successful connection.

  • Patterns 1 (i.e. Request/Reply zmq.REQ/zmq.REP) and 2 (i.e. Publish/Subscribe zmq.PUB/zmq.SUB) are the only supported values for this Mode. Therefore, calling any other pattern value with is mode will result in ValueError.

  • Multi-Servers and Multi-Clients exclusive modes CANNOT be enabled simultaneously, Otherwise NetGear API will throw ValueError.

  • The address parameter value of each Server MUST exactly match the Client.

 

Key Features

  • Enables Multiple Server(s) connection with a single Client.

  • Ability to send any additional data of any1 datatype along with frames in real-time.

  • Number of Servers can be extended to several numbers depending upon your system's hardware limit.

  • Employs powerful Publish/Subscribe & Request/Reply messaging patterns.

  • Each new Server on the network can be identified at Client's end by their unique port addresses.

  • NetGear API actively tracks the state of each connected Server.

  • If all the connected servers on the network get disconnected, the client itself automatically exits to save resources.

 

Usage Examples

Example Assumptions

  • For sake of simplicity, in these examples we will use only two unique Servers, but, the number of these Servers can be extended to several numbers depending upon your system hardware limits.

  • All of Servers will be transferring frames to a single Client system at the same time, which will be displaying received frames as a live montage (multiple frames concatenated together).

  • For building Frames Montage at Client's end, We are going to use imutils python library function to build montages, by concatenating together frames received from different servers. Therefore, Kindly install this library with pip install imutils terminal command.

 

Bare-Minimum Usage

In this example, we will capturing live video-frames on two independent sources (a.k.a Servers), each with a webcam connected to it. Afterwards, these frames will be sent over the network to a single system (a.k.a Client) using this Multi-Servers Mode in NetGear API in real time, and will be displayed as a live montage.

This example is useful for building applications like Real-Time Security System with multiple cameras.

Client's End

Open a terminal on Client System (where you want to display the input frames received from Multiple Servers) and execute the following python code:

Important Notes

  • Note down the local IP-address of this system(required at all Server(s) end) and also replace it in the following code. You can follow this FAQ for this purpose.
  • Also, assign the tuple/list of port address of all Servers you are going to connect to this system.

You can terminate client anytime by pressing Ctrl+C on your keyboard!

# import required libraries
from vidgear.gears import NetGear
from imutils import build_montages # (1)
import cv2

# activate multiserver_mode
options = {"multiserver_mode": True}

# Define NetGear Client at given IP address and assign list/tuple 
# of all unique Server((5566,5567) in our case) and other parameters
# !!! change following IP address '192.168.x.xxx' with yours !!!
client = NetGear(
    address="192.168.x.x",
    port=(5566, 5567),
    protocol="tcp",
    pattern=1,
    receive_mode=True,
    **options
)

# Define received frame dictionary
frame_dict = {}

# loop over until Keyboard Interrupted
while True:

    try:
        # receive data from network
        data = client.recv()

        # check if data received isn't None
        if data is None:
            break

        # extract unique port address and its respective frame
        unique_address, frame = data

        # {do something with the extracted frame here}

        # get extracted frame's shape
        (h, w) = frame.shape[:2]

        # update the extracted frame in the received frame dictionary
        frame_dict[unique_address] = frame

        # build a montage using data dictionary
        montages = build_montages(frame_dict.values(), (w, h), (2, 1))

        # display the montage(s) on the screen
        for (i, montage) in enumerate(montages):

            cv2.imshow("Montage Footage {}".format(i), montage)

        # check for 'q' key if pressed
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break

    except KeyboardInterrupt:
        break

# close output window
cv2.destroyAllWindows()

# safely close client
client.close()
  1. For building Frames Montage you'll need imutils python library. Install it with pip install imutils command.

 

Server-1's End

Now, Open the terminal on another Server System (with a webcam connected to it at index 0), and let's called it Server-1. Now execute the following python code:

Replace the IP address in the following code with Client's IP address you noted earlier and also assign a unique port address (required by Client to identify this system).

You can terminate stream anytime by pressing Ctrl+C on your keyboard!

# import libraries
from vidgear.gears import NetGear
from vidgear.gears import CamGear

# Open suitable video stream (webcam on first index in our case)
stream = CamGear(source=0).start()

# activate multiserver_mode
options = {"multiserver_mode": True}

# Define NetGear Server at Client's IP address and assign a unique port address and other parameters
# !!! change following IP address '192.168.x.xxx' with yours !!!
server = NetGear(
    address="192.168.x.x", port="5566", protocol="tcp", pattern=1, **options
)

# loop over until Keyboard Interrupted
while True:

    try:
        # read frames from stream
        frame = stream.read()

        # check for frame if not None-type
        if frame is None:
            break

        # {do something with the frame here}

        # send frame to server
        server.send(frame)

    except KeyboardInterrupt:
        break

# safely close video stream
stream.stop()

# safely close server
server.close()

 

Server-2's End

Finally, Open the terminal on another Server System (also with a webcam connected to it at index 0), and let's called it Server-2. Now execute the following python code:

Replace the IP address in the following code with Client's IP address you noted earlier and also assign a unique port address (required by Client to identify this system).

You can terminate stream anytime by pressing Ctrl+C on your keyboard!

# import libraries
from vidgear.gears import NetGear
from vidgear.gears import CamGear

# Open suitable video stream (webcam on first index in our case)
stream = CamGear(source=0).start()

# activate multiserver_mode
options = {"multiserver_mode": True}

# Define NetGear Server at Client's IP address and assign a unique port address and other parameters
# !!! change following IP address '192.168.x.xxx' with yours !!!
server = NetGear(
    address="192.168.x.x", port="5567", protocol="tcp", pattern=1, **options
)

# loop over until Keyboard Interrupted
while True:

    try:
        # read frames from stream
        frame = stream.read()

        # check for frame if not None-type
        if frame is None:
            break

        # {do something with the frame here}

        # send frame to server
        server.send(frame)

    except KeyboardInterrupt:
        break

# safely close video stream
stream.stop()

# safely close server
server.close()

 

 

Bare-Minimum Usage with OpenCV

In this example, we will be re-implementing previous bare-minimum example with OpenCV and NetGear API.

Client's End

Open a terminal on Client System (where you want to display the input frames received from Mutiple Servers) and execute the following python code:

Important Notes

  • Note down the local IP-address of this system(required at all Server(s) end) and also replace it in the following code. You can follow this FAQ for this purpose.
  • Also, assign the tuple/list of port address of all Servers you are going to connect to this system.

You can terminate client anytime by pressing Ctrl+C on your keyboard!

# import required libraries
from vidgear.gears import NetGear
from imutils import build_montages # (1)
import cv2

# activate multiserver_mode
options = {"multiserver_mode": True}

# Define NetGear Client at given IP address and assign list/tuple of all 
# unique Server((5566,5567) in our case) and other parameters
# !!! change following IP address '192.168.x.xxx' with yours !!!
client = NetGear(
    address="192.168.x.x",
    port=(5566, 5567),
    protocol="tcp",
    pattern=2,
    receive_mode=True,
    **options
)

# Define received frame dictionary
frame_dict = {}

# loop over until Keyboard Interrupted
while True:

    try:
        # receive data from network
        data = client.recv()

        # check if data received isn't None
        if data is None:
            break

        # extract unique port address and its respective frame
        unique_address, frame = data

        # {do something with the extracted frame here}

        # get extracted frame's shape
        (h, w) = frame.shape[:2]

        # update the extracted frame in the received frame dictionary
        frame_dict[unique_address] = frame

        # build a montage using data dictionary
        montages = build_montages(frame_dict.values(), (w, h), (2, 1))

        # display the montage(s) on the screen
        for (i, montage) in enumerate(montages):

            cv2.imshow("Montage Footage {}".format(i), montage)

        # check for 'q' key if pressed
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break

    except KeyboardInterrupt:
        break

# close output window
cv2.destroyAllWindows()

# safely close client
client.close()
  1. For building Frames Montage you'll need imutils python library. Install it with pip install imutils command.

 

Server-1's End

Now, Open the terminal on another Server System (with a webcam connected to it at index 0), and let's called it Server-1. Now execute the following python code:

Replace the IP address in the following code with Client's IP address you noted earlier and also assign a unique port address (required by Client to identify this system).

You can terminate stream anytime by pressing Ctrl+C on your keyboard!

# import libraries
from vidgear.gears import NetGear
import cv2

# Open suitable video stream (webcam on first index in our case)
stream = cv2.VideoCapture(0)

# activate multiserver_mode
options = {"multiserver_mode": True}

# Define NetGear Server at Client's IP address and assign a unique port address and other parameter
# !!! change following IP address '192.168.x.xxx' with yours !!!
server = NetGear(
    address="192.168.x.x", port="5566", protocol="tcp", pattern=2, **options
)

# loop over until Keyboard Interrupted
while True:

    try:
        # read frames from stream
        (grabbed, frame) = stream.read()

        # check for frame if not grabbed
        if not grabbed:
            break

        # {do something with the frame here}

        # send frame to server
        server.send(frame)

    except KeyboardInterrupt:
        break

# safely close video stream
stream.release()

# safely close server
server.close()

 

Server-2's End

Finally, Open the terminal on another Server System (also with a webcam connected to it at index 0), and let's called it Server-2. Now execute the following python code:

Replace the IP address in the following code with Client's IP address you noted earlier and also assign a unique port address (required by Client to identify this system).

You can terminate stream anytime by pressing Ctrl+C on your keyboard!

# import libraries
from vidgear.gears import NetGear
import cv2

# Open suitable video stream (webcam on first index in our case)
stream = cv2.VideoCapture(0)

# activate multiserver_mode
options = {"multiserver_mode": True}

# Define NetGear Server at Client's IP address and assign a unique port address and other parameters
# !!! change following IP address '192.168.x.xxx' with yours !!!
server = NetGear(
    address="192.168.x.x", port="5567", protocol="tcp", pattern=2, **options
)

# loop over until Keyboard Interrupted
while True:

    try:
        # read frames from stream
        (grabbed, frame) = stream.read()

        # check for frame if not grabbed
        if not grabbed:
            break

        # {do something with the frame here}

        # send frame to server
        server.send(frame)

    except KeyboardInterrupt:
        break

# safely close video stream
stream.release()

# safely close server
server.close()

 

 

Using Multi-Servers Mode for Unidirectional Custom Data Transfer

Abstract

With Multi-Servers Mode, you can send additional data of any datatype1 along with frame with frame in real-time, from all connected Server(s) to a single Client unidirectionally.

But numpy.ndarray data-type is NOT supported as data.

In this example, We will be transferring video-frames and data (a Text String, for the sake of simplicity) from two Servers (consisting of a Raspberry Pi with Camera Module & a Laptop with webcam) to a single Client over the network in real-time. The received video-frames at Client's end will displayed as a live montage, whereas the received data will be printed to the terminal.

Client's End

Open a terminal on Client System (where you want to display the input frames received from Mutiple Servers) and execute the following python code:

Important Notes

  • Note down the local IP-address of this system(required at all Server(s) end) and also replace it in the following code. You can follow this FAQ for this purpose.
  • Also, assign the tuple/list of port address of all Servers you are going to connect to this system.

You can terminate client anytime by pressing Ctrl+C on your keyboard!

# import required libraries
from vidgear.gears import NetGear
from imutils import build_montages # (1)
import cv2

# activate multiserver_mode
options = {"multiserver_mode": True}

# Define NetGear Client at given IP address and assign list/tuple of all unique Server((5577,5578) in our case) and other parameters
# !!! change following IP address '192.168.x.xxx' with yours !!!
client = NetGear(
    address="192.168.x.x",
    port=(5577, 5578),
    protocol="tcp",
    pattern=1,
    receive_mode=True,
    logging=True,
    **options
)  
# Define received frame dictionary
frame_dict = {}

# loop over until Keyboard Interrupted
while True:

    try:
        # receive data from network
        data = client.recv()

        # check if data received isn't None
        if data is None:
            break

        # extract unique port address and its respective frame and received data
        unique_address, extracted_data, frame = data

        # {do something with the extracted frame and data here}
        # let's display extracted data on our extracted frame
        cv2.putText(
            frame,
            extracted_data,
            (10, frame.shape[0] - 10),
            cv2.FONT_HERSHEY_SIMPLEX,
            0.6,
            (0, 255, 0),
            2,
        )

        # get extracted frame's shape
        (h, w) = frame.shape[:2]

        # update the extracted frame in the frame dictionary
        frame_dict[unique_address] = frame

        # build a montage using data dictionary
        montages = build_montages(frame_dict.values(), (w, h), (2, 1))

        # display the montage(s) on the screen
        for (i, montage) in enumerate(montages):

            cv2.imshow("Montage Footage {}".format(i), montage)

        # check for 'q' key if pressed
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break

    except KeyboardInterrupt:
        break

# close output window
cv2.destroyAllWindows()

# safely close client
client.close()
  1. For building Frames Montage you'll need imutils python library. Install it with pip install imutils command.

 

Server-1's End

Now, Open the terminal on another Server System (with a webcam connected to it at index 0), and let's called it Server-1. Now execute the following python code:

Replace the IP address in the following code with Client's IP address you noted earlier and also assign a unique port address (required by Client to identify this system).

You can terminate stream anytime by pressing Ctrl+C on your keyboard!

# import libraries
from vidgear.gears import NetGear
from vidgear.gears import VideoGear
import cv2

# Open suitable video stream (webcam on first index in our case)
stream = VideoGear(source=0).start()

# activate multiserver_mode
options = {"multiserver_mode": True}

# Define NetGear Server at Client's IP address and assign a unique port address and other parameters
# !!! change following IP address '192.168.x.xxx' with yours !!!
server = NetGear(
    address="192.168.x.x",
    port="5577",
    protocol="tcp",
    pattern=1,
    logging=True,
    **options
)

# loop over until Keyboard Interrupted
while True:

    try:
        # read frames from stream
        frame = stream.read()

        # check for frame if Nonetype
        if frame is None:
            break

        # {do something with frame and data(to be sent) here}

        # let's prepare a text string as data
        target_data = "I'm Server-1 at Port: 5577"

        # send frame and data through server
        server.send(frame, message=target_data) # (1)

    except KeyboardInterrupt:
        break

# safely close video stream
stream.stop()

# safely close server
server.close()
  1. ⚠ Everything except numpy.ndarray datatype data is accepted as target_data in message parameter.

 

Server-2's End

Finally, Open the terminal on another Server System (this time a Raspberry Pi with Camera Module connected to it), and let's called it Server-2. Now execute the following python code:

Replace the IP address in the following code with Client's IP address you noted earlier and also assign a unique port address (required by Client to identify this system).

You can terminate stream anytime by pressing Ctrl+C on your keyboard!

# import libraries
from vidgear.gears import NetGear
from vidgear.gears import PiGear
import cv2

# add various Picamera tweak parameters to dictionary
options = {
    "hflip": True,
    "exposure_mode": "auto",
    "iso": 800,
    "exposure_compensation": 15,
    "awb_mode": "horizon",
    "sensor_mode": 0,
}

# open pi video stream with defined parameters
stream = PiGear(resolution=(640, 480), framerate=60, logging=True, **options).start()

# activate multiserver_mode
options = {"multiserver_mode": True}

# Define NetGear Server at Client's IP address and assign a unique port address and other parameters
# !!! change following IP address '192.168.x.xxx' with yours !!!
server = NetGear(
    address="192.168.1.xxx",
    port="5578",
    protocol="tcp",
    pattern=1,
    logging=True,
    **options
)

# loop over until Keyboard Interrupted
while True:

    try:
        # read frames from stream
        frame = stream.read()

        # check for frame if Nonetype
        if frame is None:
            break

        # {do something with frame and data(to be sent) here}

        # let's prepare a text string as data
        text = "I'm Server-2 at Port: 5578"

        # send frame and data through server
        server.send(frame, message=text)

    except KeyboardInterrupt:
        break

# safely close video stream.
stream.stop()

# safely close server
server.close()

 

 

Using Multi-Servers Mode with Bidirectional Mode

Abstract

Multi-Servers Mode now also compatible with Bidirectional Mode, which lets you send additional data of any datatype1 along with frame in real-time bidirectionally between a single Client and all connected Server(s).

Important Information

  • Bidirectional data transfer ONLY works with pattern 1 (i.e. Request/Reply zmq.REQ/zmq.REP), and NOT with pattern 2 (i.e. Publish/Subscribe zmq.PUB/zmq.SUB)
  • Additional data of numpy.ndarray data-type is NOT SUPPORTED at Server(s) with their message parameter.
  • Bidirectional Mode may lead to additional LATENCY depending upon the size of data being transfer bidirectionally. User discretion is advised!
New in v0.2.5

This example was added in v0.2.5.

In this example, We will be transferring video-frames and data (a Text String, for the sake of simplicity) from two Servers (consisting of a Raspberry Pi with Camera Module & a Laptop with webcam) to a single Client, and at same time sending back data (a Text String, for the sake of simplicity) to them over the network all in real-time. The received video-frames at Client's end will displayed as a live montage, whereas the received data will be printed to the terminal.

Client's End

Open a terminal on Client System (where you want to display the input frames received from Mutiple Servers) and execute the following python code:

Important Notes

  • Note down the local IP-address of this system(required at all Server(s) end) and also replace it in the following code. You can follow this FAQ for this purpose.
  • Also, assign the tuple/list of port address of all Servers you are going to connect to this system.

You can terminate client anytime by pressing Ctrl+C on your keyboard!

# import required libraries
from vidgear.gears import NetGear
from imutils import build_montages # (1)
import cv2

# activate both multiserver and bidirectional modes
options = {"multiserver_mode": True, "bidirectional_mode": True}

# Define NetGear Client at given IP address and assign list/tuple of all unique Server((5577,5578) in our case) and other parameters
# !!! change following IP address '192.168.x.xxx' with yours !!!
client = NetGear(
    address="192.168.x.x",
    port=(5577, 5578),
    protocol="tcp",
    pattern=1,
    receive_mode=True,
    logging=True,
    **options
)  
# Define received frame dictionary
frame_dict = {}

# loop over until Keyboard Interrupted
while True:

    try:
        # prepare data to be sent
        target_data = "Hi, I am a Client here."

        # receive data from server(s) and also send our data
        data = client.recv(return_data=target_data)

        # check if data received isn't None
        if data is None:
            break

        # extract unique port address and its respective frame and received data
        unique_address, extracted_data, frame = recv_data

        # {do something with the extracted frame and data here}
        # let's display extracted data on our extracted frame
        cv2.putText(
            frame,
            extracted_data,
            (10, frame.shape[0] - 10),
            cv2.FONT_HERSHEY_SIMPLEX,
            0.6,
            (0, 255, 0),
            2,
        )

        # get extracted frame's shape
        (h, w) = frame.shape[:2]

        # update the extracted frame in the frame dictionary
        frame_dict[unique_address] = frame

        # build a montage using data dictionary
        montages = build_montages(frame_dict.values(), (w, h), (2, 1))

        # display the montage(s) on the screen
        for (i, montage) in enumerate(montages):

            cv2.imshow("Montage Footage {}".format(i), montage)

        # check for 'q' key if pressed
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break

    except KeyboardInterrupt:
        break

# close output window
cv2.destroyAllWindows()

# safely close client
client.close()
  1. For building Frames Montage you'll need imutils python library. Install it with pip install imutils command.

 

Server-1's End

Now, Open the terminal on another Server System (with a webcam connected to it at index 0), and let's called it Server-1. Now execute the following python code:

Replace the IP address in the following code with Client's IP address you noted earlier and also assign a unique port address (required by Client to identify this system).

You can terminate stream anytime by pressing Ctrl+C on your keyboard!

# import libraries
from vidgear.gears import NetGear
from vidgear.gears import VideoGear
import cv2

# Open suitable video stream (webcam on first index in our case)
stream = VideoGear(source=0).start()

# activate both multiserver and bidirectional modes
options = {"multiserver_mode": True, "bidirectional_mode": True}

# Define NetGear Server at Client's IP address and assign a unique port address and other parameters
# !!! change following IP address '192.168.x.xxx' with yours !!!
server = NetGear(
    address="192.168.x.x",
    port="5577",
    protocol="tcp",
    pattern=1,
    logging=True,
    **options
)

# loop over until Keyboard Interrupted
while True:

    try:
        # read frames from stream
        frame = stream.read()

        # check for frame if Nonetype
        if frame is None:
            break

        # {do something with frame and data(to be sent) here}

        # let's prepare a text string as data
        target_data = "I'm Server-1 at Port: 5577"

        # send frame & data and also receive data from Client
        recv_data = server.send(frame, message=target_data) # (1)

        # print data just received from Client
        if not (recv_data is None):
            print(recv_data)

    except KeyboardInterrupt:
        break

# safely close video stream
stream.stop()

# safely close server
server.close()
  1. ⚠ Everything except numpy.ndarray datatype data is accepted as target_data in message parameter.

 

Server-2's End

Finally, Open the terminal on another Server System (this time a Raspberry Pi with Camera Module connected to it), and let's called it Server-2. Now execute the following python code:

Replace the IP address in the following code with Client's IP address you noted earlier and also assign a unique port address (required by Client to identify this system).

You can terminate stream anytime by pressing Ctrl+C on your keyboard!

# import libraries
from vidgear.gears import NetGear
from vidgear.gears import PiGear
import cv2

# add various Picamera tweak parameters to dictionary
options = {
    "hflip": True,
    "exposure_mode": "auto",
    "iso": 800,
    "exposure_compensation": 15,
    "awb_mode": "horizon",
    "sensor_mode": 0,
}

# open pi video stream with defined parameters
stream = PiGear(resolution=(640, 480), framerate=60, logging=True, **options).start()

# activate both multiserver and bidirectional modes
options = {"multiserver_mode": True, "bidirectional_mode": True}

# Define NetGear Server at Client's IP address and assign a unique port address and other parameters
# !!! change following IP address '192.168.x.xxx' with yours !!!
server = NetGear(
    address="192.168.1.xxx",
    port="5578",
    protocol="tcp",
    pattern=1,
    logging=True,
    **options
)

# loop over until Keyboard Interrupted
while True:

    try:
        # read frames from stream
        frame = stream.read()

        # check for frame if Nonetype
        if frame is None:
            break

        # {do something with frame and data(to be sent) here}

        # let's prepare a text string as data
        target_data = "I'm Server-2 at Port: 5578"

        # send frame & data and also receive data from Client
        recv_data = server.send(frame, message=target_data) # (1)

        # print data just received from Client
        if not (recv_data is None):
            print(recv_data)

    except KeyboardInterrupt:
        break

# safely close video stream.
stream.stop()

# safely close server
server.close()
  1. ⚠ Everything except numpy.ndarray datatype data is accepted as target_data in message parameter.

 


  1. Additional data of numpy.ndarray data-type is NOT SUPPORTED at Server(s) with their message parameter.


Last update: July 31, 2022