1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Python でシンプルなオウム返しをする WebSocketサーバーを作ってみる(+ Node.js のクライアントからメッセージを送ってみる)

Last updated at Posted at 2025-02-08

はじめに

ローカルLLM を扱うプログラムを外部のアプリ・プログラムと連携させたいと考えていて、いったんそれに活用できそうなリアルタイム通信を試してみる話です。

それで、WebSocket を扱ってみようと思います。

JavaScript でリアルタイム通信

リアルタイム通信自体は、過去に JavaScript(Node.js、ブラウザで動作させるものの両方)や、IoT に使えるデバイスで扱っていて、WebSocket や MQTT を使っていました。

過去に書いている記事

Qiita にもたくさん記事を書いていて、キーワード + ユーザー名での検索をかけると、それらが出てきます。

●「websocket user:youtoy」の検索結果 - Qiita
 https://qiita.com/search?q=websocket%20user%3Ayoutoy&sort=created

●「mqtt user:youtoy」の検索結果 - Qiita
 https://qiita.com/search?sort=created&q=mqtt+user%3Ayoutoy

WebSocket を扱う場合、WebSocketサーバーはよく ws を使っていたりします。

Python でシンプルな WebSocketサーバー

今回、Python でシンプルな WebSocketサーバーを作ってみます。

ベースを ChatGPT で作る

ベースのところは、まずは ChatGPT(モデルは o3-mini-high)で生成してみます。

そうすると、以下のような内容を提示されました。

import asyncio
import websockets

async def echo(websocket, path):
    print("クライアントが接続しました")
    try:
        async for message in websocket:
            print(f"受信: {message}")
            response = f"Echo: {message}"
            await websocket.send(response)
            print(f"送信: {response}")
    except websockets.exceptions.ConnectionClosed:
        print("クライアントとの接続が閉じられました")

async def main():
    # localhost の 8765 番ポートでサーバーを起動
    async with websockets.serve(echo, "localhost", 8765):
        print("WebSocketサーバーが起動しました")
        await asyncio.Future()  # 永久に待機

if __name__ == '__main__':
    asyncio.run(main())

以下の 2つを使った実装になるようです。

●websockets · PyPI
 https://pypi.org/project/websockets/

●asyncio · PyPI
 https://pypi.org/project/asyncio/

ドキュメント等を確認して書きかえる

とりあえず、上で書いたページの中の websockets の方を見てみます。

2025-02-09_01-48-35.jpg

あわせてドキュメントも参照してみます。

●websockets 14.2 documentation
 https://websockets.readthedocs.io/en/stable/

2025-02-09_02-06-46.jpg

書きかえ後の内容

それらを見つつ、先ほどのプログラムを以下のようにしてみました。

import asyncio
from websockets.asyncio.server import serve

async def echo(websocket):
    print("クライアントが接続しました")
    try:
        async for message in websocket:
            print(f"受信: {message}")
            response = f"Echo: {message}"
            await websocket.send(response)
            print(f"送信: {response}")
    except Exception as e:
        print("エラー:", e)
    finally:
        print("クライアントとの接続が終了しました")

async def main():
    async with serve(echo, "localhost", 8765) as server:
        print("WebSocketサーバーが起動しました")
        await server.serve_forever()


if __name__ == '__main__':
    asyncio.run(main())

最初に掲載していたものと websockets.asyncio.serverserver.serve_forever() というあたりは変えていますが、その部分は公式のドキュメントの以下を参照して書きかえたものです。

●Server (new asyncio) - websockets 14.2 documentation
 https://websockets.readthedocs.io/en/stable/reference/asyncio/server.html

仮想環境で動かす

上記を仮想環境で動かすことにします。

まずは以下で仮想環境の作成などを行います(※ 以下の 2行目は Mac用の処理です)。

python -m venv myenv
source myenv/bin/activate

次に仮想環境内で websockets をインストールします。

pip install websockets

そしてこの環境で、上記の Python のプログラムを実行してみます。

クライアントから接続

さらに、クライアントから接続してみます。

Node.js からの接続を試します。
以前、以下の記事で書いたように Node.js v22 以降では、デフォルトで WebSocket のクライアントの処理が扱えます。

●Node.js と ws でシンプルな WebSocketサーバー + Node.js v22 でフラグなしで使える WebSocket - Qiita
 https://qiita.com/youtoy/items/9e1eeae728dc98f15679

上記の記事で書いた、以下のプログラムを使うことにします。

const socket = new WebSocket("ws://localhost:8765");

socket.addEventListener("open", (event) => {
  socket.send("Hello Server!");
});

socket.addEventListener("message", (event) => {
  console.log("Message from server ", event.data);
});

上記を実行した後の、サーバー側の出力を確認してみます。

2025-02-09_02-15-14.jpg

上記のとおり、クライアントからのメッセージを受信し、そしてオウム返しをしています。

その後のクライアント側の出力も確認してみます。

2025-02-09_02-17-43.jpg

サーバーからのオウム返しされたメッセージを受信できているのが分かります。

また、メッセージの内容を少しだけ変えた 2つ目のクライアントを用意し、それを実行してみます。
その結果、以下のように 2つめのクライアントからのメッセージの受信と、それに対するオウム返しが成功しているのが分かります。

2025-02-09_02-16-42.png

ひとまず簡単なものですが、Python の WebSocketサーバーと、Node.js の WebSocketクライアントとの間での通信ができたことが確認できました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?