sndcpyのサーバーに複数クライアントから接続できるようにした話
前回に続きsndcpy関連の話です。 sndcpyのサーバーは、ソースコードを読むと分かるように複数クライアントの接続を想定していません。 そのため、録音しながらモニタリングできないのです。ならば複数接続できるようにしてやろう、ということでPythonでTCPサーバーを作ります。 仕組み まず、すべてのクライアントに同じデータを送信する必要があります。 1つの変数にデータを入れていって、各クライアントを処理するプロセスがそれを読み取ればいいのではないかと考える方もいるかと思いますが、それだと矛盾が起きたり後にバグに繋がる可能性があるので、クライアントごとにキューを持たせ、sndcpyのサーバーからデータを受け取ってそれぞれのキューに入れていくようにします。クライアントに配信するプロセスは自身のキューを読むだけで済むのでバグの原因になりにくいです。 実装 まずsndcpyのサーバーに接続します。 sndcpy = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sndcpy.connect(('localhost', 28200)) threadingを使ってバッググラウンドでキューに貯めていってもらいます。 queuesという配列に入っているクライアントに全部入れています。 queues = [] stopFlag = False def data_queue(): while not stopFlag: data = sndcpy.recv(1024) for q in queues: q: queue.Queue = q['queue'] q.put(data) data_queue_thread = threading.Thread(target=data_queue) data_queue_thread.start() stopFlagを用意しているのはプログラムが完全に止まるようにするためです。 スレッドが動いているとメインプログラムが終了してもいつまでも全体が止まりません。Ctrl+Cでも止められなくなります。 次にキュー管理用の関数を作ります。 def create_queue(): qid = str(uuid.uuid4()) d = {'queue': queue.Queue(), 'id': qid} queues.append(d) return qid def get_queue(qid): for q in queues: if q['id'] == qid: return q def delete_queue(qid): for q in queues: if q['id'] == qid: queues....