IoT+WEBのためのホームサーバ計画の3、IoTコントローラからUDPで通知、TCP/IPでやりとり

ホームサーバと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 ]
●

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です