オブジェクトの参照が面倒
オブジェクトが多くなってくるとオブジェクト同士の通信が億劫になってきます。親とか子とかパスとか、も~めんどくさい! たまには違うプログラムとやり取りなんかも発生して本当に大変。
ならばネットワークだ! 昔から利用されていた方法だから間違いはない。(はず)
お手軽通信、UDP
やっぱりこういう目的ならUDPでしょう。Open Sound Controlもちらっと考えたのですがモジュールとか導入したり諸々面倒なのでPythonで何も考えずに使えるudpで済ますことにしました。
受信を待つとかブロッキングで他の処理が止まるとかそういうのは使いづらくて困るのでデータが受信されたらコールバックが呼ばれるって感じで。
うん、なんか良さそうな気がしてきたぞ。
コード
そんな感じでとりあえずでっち上げました。行儀悪いところがあったりするけど細かいツッコミは必要ないので気になるなら直して使うなり自由にすると良いです。
比較的簡単に使える、気をつけなきゃいけないのはIPアドレスが被らないようにすることくらい。
udpnet.py
import socket
import threading
def thread(func):
def run(*args, **kwargs):
t = threading.Thread(target=func, args=args, kwargs=kwargs)
t.start()
return run
class UDP:
def __init__(self, ADDR):
self.addr = ADDR
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.bind(self.addr)
self.running = True
self.callback = None
def messageRecieved(self, callback=None):
self.callback = callback
@thread
def mainloop(self):
while self.running:
try:
data, addr = self.sock.recvfrom(8192)
except:
continue
if data.decode() == "quit_request":
break
if self.callback:
self.callback({"data": data.decode(),
"address": addr,
"sock": self})
def send(self, msg, ADDR):
self.sock.sendto(msg.encode(), ADDR)
def close(self):
self.running = False
self.send("quit_request", self.addr)
self.sock.close()
self.sock = None
使い方。
dict型のデータがやり取り出来れば不自由ないだろうということでそういうデモ。
二つのホストがやり取りするような内容。
つくった udpnet.py はあまり高速通信を得意とするような構造をしていないのでリアルタイムでだらだらデータストリーミングするような目的では使わない方が良いと思います。あくまでなにやらの処理のときにリクエスト → データを受け取って次の処理を呼ぶ。みたいな感じがよろしいかと。
import udpnet
import time
import json
# UDPホストその1 用のコールバック
# データの内容を表示して送信元へ返信を行う
def sevRcv(x):
dat = json.loads(x["data"])
for key in dat.keys():
print(key, dat[key])
x["sock"].send("welcome", x["address"])
#
# UDPホストその1
#
s0 = udpnet.UDP(("127.0.0.1", 49200))
s0.messageRecieved(sevRcv)
s0.mainloop()
#
# udpホストその2
#
s1 = udpnet.UDP(("127.0.0.2", 49200))
s1.mainloop()
# ホストその2 はコールバックをラムダで処理してみる
s1.messageRecieved(lambda x: print("recieved!:", x["data"]))
#
# 1秒おきに10回ほどホストその2から1へ送信をする
#
for i in range(10):
dat = {"a": 123, "b": "hello"}
s1.send(json.dumps(dat), ("127.0.0.1", 49200))
time.sleep(1)
# ホストを閉じて終わり
s0.close()
s1.close()
〆
まだ実戦投入してませんがヒエラルキーをガン無視できて大分自由に楽々になるんじゃないかと期待度高めです。
Pythonだとこういうのも簡単に書けていいですね。
さらなる展望としてはデータクラスと融合させて変数にアクセスするようなノリで通信が出来たらいいですねー。