IoT+WEBのためのホームサーバ計画の3、IoTコントローラからUDPで通知、TCP/IPでやりとり
2020-02-08
ホームサーバとIoTコントローラの接続で、
前回はIoTコントローラ側からUDPでサーバへIPを通知するとこまでだったので、
そっからTCP/IPで情報のやりとりをする部分を書いてみましょう。
まず、サーバ側が立ち上がってる前提で、
IoTコントローラ➡( UDPでブロキャス)➡サーバ
サーバはIPが通知されるので、
サーバ➡ (TCP/IPでメッセージ ) ➡IoTコントローラ➡(情報を返す)➡サーバ
という流れです。
情報の中身としては、サーバ側はIoTコントローラを固有のIDで管理したいので、
サーバ側からとりあえずIDを送信します。
コントローラ側は、自分のIDを既に持っていればそれを使い、
持ってなければ、送信されてきたものを保存しときます。
まぁ、最初の方でTCP/IPのテストはしてるので、問題は特になく、
だいたいこんな感じです。
※ IDをあれこれする部分は 省略
サーバ側
#-------------------------------------------------------
import sys
import socket
import traceback
import time
import threading
import multiprocessing
import uuid
import json
#--------------------------------------
from hiraSockUDP import hiraSockUDP
from hiraSockTCP import hiraSockTCP
#--------------------------------------
HIRA_USE_UDP_PORT = 60011
HIRA_USE_TCP_PORT = 60009
#--------------------------------------
#if __name__ == '__main__':
#----------------------------------
def udpRecv(adr,dat):
if dat == b'FINRED_BROADING':
print("adr;{} dat;{}".format(adr,dat))
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.setsockopt(socket.SOL_SOCKET,socket.SO_SNDBUF,65536)
s.setsockopt(socket.SOL_SOCKET,socket.SO_RCVBUF,65536)
s.connect((adr,HIRA_USE_TCP_PORT))
gid = str(uuid.uuid4()) #u4 = str(uuid.uuid4())
cmd = {"sign":"FINRED","cmd":"GETINFO","uuid":gid}
cmds = json.dumps(cmd,separators=(',', ':'))
s.sendall(cmds.encode('utf-8'))
data = s.recv(65536)
print("recv:",data)
#----------------------------------
def udpRecvExec():
U = hiraSockUDP()
U.setFunc(udpRecv)
U.exec()
#----------------------------------
if __name__ == '__main__':
P = multiprocessing.Process(target = udpRecvExec)
P.start()
#----------------------------------
クライアント側
#-------------------------------------------------------
import sys
import json
import socket
import traceback
import time
import threading
import multiprocessing
#--------------------------------------
from hiraSockUDPC import hiraSockUDPC
from hiraSockTCP import hiraSockTCP
#--------------------------------------
HIRA_USE_UDP_PORT = 60011
HIRA_USE_TCP_PORT = 60009
#--------------------------------------
if __name__ == '__main__':
#----------------------------------
# TCPでなんか受け取る
# 受けるときはJSONのみにしとく。
#----------------------------------
def reciever(conn,mes,alter):
try:
o = json.loads(mes)
sign = o['sign']
cmd = o['cmd']
print("called [",cmd,"]")
if sign != "FINRED":
raise()
if cmd == "GETINFO":
ret = {"status":"OK","uuid":o['uuid']}
rets = json.dumps(ret,separators=(',', ':'))
else:
raise()
conn.sendall(rets.encode('utf-8'))
except Exception as e:
ret = {"status":"NG"}
rets = json.dumps(ret,separators=(',', ':'))
conn.sendall(rets.encode('utf-8'))
#----------------------------------
def watcher():
print("--watcher start--")
laddress = socket.gethostbyname(socket.gethostname())
with hiraSockTCP(laddress,HIRA_USE_TCP_PORT) as S:
S.setFunc(reciever)
S.exec()
#----------------------------------
# UDPで知らせる方。
#----------------------------------
def register():
while True:
C = hiraSockUDPC()
C.exec("FINRED_BROADING")
print("upto FINRED_BROADING")
time.sleep(300)
#----------------------------------
r = threading.Thread(target=register)
r.start()
#----------------------------------
t = threading.Thread(target=watcher)
t.start()
#----------------------------------
#--------------------------------------
サーバ側実行画面
#-------------------------
m_cast_group; 239.255.255.250
port; 60011
myIP: 192.168.11.181
#-------------------------
adr;192.168.11.181 dat;b'FINRED_BROADING'
recv: b'{"status":"OK","uuid":"ba0b5028-5a9c-4f7a-92f4-798a123e8d11"}'
クライアント側実行画面
--watcher start--
upto FINRED_BROADING
Address:192.168.11.181 Port:60009
called [ GETINFO ]
●