Exchanging Messages: Advanced Usage

The examples here all refer to the messenger module.

News from more than one source

Process A, B, C and D

import networkzero as nw0
import random
import time
import uuid

name = "movement/%s" % uuid.uuid1().hex
address = nw0.advertise(name)
print("Sending from %s -> %s" % (name, address))

#
# In lieu of an actual sensor!
#
while True:
    is_movement = random.random() > 0.5
    nw0.send_news_to(address, "movement", (name, is_movement))
    time.sleep(random.random())

Process E

import networkzero as nw0

addresses = [address for name, address in nw0.discover_group("movement")]

while True:
    topic, (sensor, is_movement) = nw0.wait_for_news_from(addresses)
    if is_movement:
        print("Movement from %s!!!" % sensor)

Discussion

A process can listen for news from more than one source. For example, if you have four movement sensors, one in each corner of a room, all ending their updates on the same channel, you can gather updates from all four at once.

Sending Data

Process A

import os, sys
import tempfile
import networkzero as nw0

address = nw0.advertise("gallery")
print("Gallery:", address)
while True:
    filename, data = nw0.wait_for_message_from(address, autoreply=True)
    bytes = nw0.string_to_bytes(data)
    
    temp_filepath = os.path.join(tempfile.gettempdir(), filename)
    with open(temp_filepath, "wb") as f:
        f.write(bytes)
    print("Wrote", temp_filepath)

Process B

import os, sys
import networkzero as nw0

try:
    input = raw_input
except NameError:
    pass

gallery = nw0.discover("gallery")
filepath = input("Filename: ")
filename = os.path.basename(filepath)
with open(filepath, "rb") as f:
    data = f.read()
    
nw0.send_message_to(gallery, (filename, nw0.bytes_to_string(data)))

Discussion

Sometimes the data you want to send isn’t text or numbers: it’s binary data—bytes—such as the bytes which make up an image or a sound file. To send that via networkzero you have to treat it specially: at the sending end, you convert it to a string; and at the receiving end, you convert it back into bytes.

Polling

Process A

import time
import networkzero as nw0

address = nw0.advertise("poller1")

while True:
    message = nw0.wait_for_message_from(address, wait_for_s=0)
    if message is not None:
        print("Received:", message)
        nw0.send_reply_to(address, "Received: %s" % message)
        break
    else:
        print("Doing other useful things ...")
        time.sleep(1)

Process B

import time
import networkzero as nw0

service = nw0.discover("poller1")

time.sleep(3)
reply = nw0.send_message_to(service, "This is a message")
print("Reply: ", reply)

Discussion

By default, when you wait for a network message, your process blocks: that is, it won’t do anything else until a message arrives. Sometimes that’s perfectly sensible: if your robot can’t go anywhere until it knows where to go then the process must block until it receives an instruction.

Sometimes, though, you want to be able to get on with other things while waiting for a message to arrive on the network. There are several approaches to this in general: threading, asynchronous IO, event loops… and polling. Polling is the simplest of these and is easy to do with networkzero: you simply check for a message briefly before carrying on. If a message has arrived, you can act on it; otherwise, you do the other things you want to do (for example update your game screen, have your robot check its sensors, etc.)