How to solve this simple one-way local machine messaging problem

Question:

I have a first sender script in Python 3.10 which needs to send some data

def post_updates(*args):
   sender.send_message("optional_key", args)

Then a second receiver script in Python 3.7 which needs to receive this data

while True:
   args = receiver.get_message("optional_key", blocking=True)
   print("args received:", args)

Constraints:

  • Each script should not depend on the presence of the other to run.
  • The sender should try to send regardless if the receiver is running.
  • The receiver should try to receive regardless if the sender is running.
  • The message can consist of basic python objects (dict, list) and should be serialized automatically.
  • I need to send over 100 messages per second (minimizing latency if possible).
  • Local PC only (Windows) and no need for security.

Are there 1-liner solutions to this simple problem? Everything I look up seems overly complicated or requires a TCP server to be started beforehand. I don’t mind installing popular modules.

Asked By: BinaryMonkey

||

Answers:

The good old pipe might do the job, but you need to assess how big the buffer size needs to be (given the async nature of your sender/receiver), and change the default pipe buffer size.

Answered By: Redexing

UDP and JSON look perfect for what you’re asking for, as long as

  • you don’t need there to be more than one receiver
  • you don’t need very large messages
  • you just need to send combinations of dicts, lists, strings, and numbers, not Python objects of arbitrary classes
  • you’re not being overly literal about finding a "1-liner": it’s a very small amount of code to write, and you’re free to define your own helper functions.

Python’s standard library has all you need for this. Encoding and decoding from JSON is as simple as json.dumps() and json.loads(). For sending and receiving, I suggest following the example on the Python wiki. You need to create the socket first with

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

regardless of if you’re making the sender or the receiver. The receiver will then need to bind to the local port to listen to it:

sock.bind(('127.0.0.1', PORT))

And then the sender sends with sock.sendto() and the receiver receives with sock.recvfrom().

Answered By: Dan Getz
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.