2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

サーバ上のpythonとブラウザ上のjavascriptとデータ通信を行う

Last updated at Posted at 2022-10-23

やりたいこと

  • pythonで簡単なゲームのプログラムを書いた。
  • HTMLを駆使しながら、ブラウザ上の「GUI」でこのゲームができるようにしたい。
    → javascriptとpythonでデータのやり取りができれば大体OK

この記事で説明すること

ここでは WebSocket の基本的な使い方をまとめておきます。

  • javascript ↔ pythonのデータ通信が簡単に実装できる。
  • ゲームユーザ(クライアント)がゲームから途中離脱した場合などの接続管理が簡単になるっぽい。複数人が個別でバラバラに接続してもOK。

さっそくサンプル

使い方

  1. webscoketsをpython環境にインストール
    conda install -c conda-forge websocketsを実行すればOK。簡単。

  2. 下のserver.pyを保存して実行。

server.py
'''Echoサーバの実装'''
import asyncio
import websockets

# この関数に通信しているときに行う処理を書く。
# クライアントが接続している間は下の関数が常に回っている
async def handler(websocket):
    # クライアントからのメッセージを取り出してそのまま送り返す(Echo)
    async for message in websocket:
        await websocket.send(message)

async def main():
    async with websockets.serve(handler, "localhost", 8001):
        await asyncio.Future()  # run forever

asyncio.run(main()
  1. 下のindex.htmlを保存してブラウザ上で起動。
index.html
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>Websocket Demo</title>
</head>
<body>
  <!-- ==========ここからHTML本体========== -->
  <!-- テキストフォームとボタン -->
  <form>
    <input id="textMessage" type="text">
    <input onclick="connect()" value="Connect" type="button">
    <input onclick="sendMessage()" value="Send" type="button">
    <input onclick="disconnect()" value="Disconnect" type="button">
  </form>
  <br />
  <!-- テキスト出力エリア -->
  <textarea id="messageTextArea" rows="10" cols="50"></textarea>


  <!-- ==========ここからjavascript========== -->
  <script type="text/javascript">

    var webSocket; //ウェブソケット
    var messageTextArea = document.getElementById("messageTextArea"); // HTML内のテキスト出力エリア

    // サーバとの通信を接続する関数
    function connect(){
      webSocket = new WebSocket("ws://localhost:8001"); // インスタンスを作り、サーバと接続

      // ソケット接続すれば呼び出す関数を設定
      webSocket.onopen = function(message){
        messageTextArea.value += "Server connect... OK\n";
      };

      // ソケット接続が切ると呼び出す関数を設定
      webSocket.onclose = function(message){
        messageTextArea.value += "Server Disconnect... OK\n";
      };

      // ソケット通信中でエラーが発生すれば呼び出す関数を設定
      webSocket.onerror = function(message){
        messageTextArea.value += "error...\n";
      };

      // ソケットサーバからメッセージが受信すれば呼び出す関数を設定
      webSocket.onmessage = function(message){
        messageTextArea.value += "Receive => "+message.data+"\n";
      };
    }

    // サーバにメッセージを送信する関数
    function sendMessage(){
      var message = document.getElementById("textMessage");
      messageTextArea.value += "Send => "+message.value+"\n";
      webSocket.send(message.value);
      message.value = "";
    }

    // サーバとの通信を切断する関数
    function disconnect(){
      webSocket.close();
    }
  </script>

</body>
</html>

実際に使っているところ

Connectボタンを押して接続し、適当な文字列を入力してSendボタンを押した結果。
そのまま文字列がサーバから返却されている。

image.png

参考

次のページを参考に勉強させていただきました。感謝。(ほとんど写経)
https://www.nowonbun.com/247.html

おわりに

  • 一応RESTでも作れるが、ゲームとの接続管理をもっと簡単に作れたのでwebsocketはわりと良かった。
  • このソースコードを魔改造するとゲーム用GUIがブラウザ上でつくれる。

(おまけ)ブラウザとの通信方法

  • REST API

    • ざっくり説明
      • 最も基本的なサーバとの通信方式
      • GETなどを使ってサーバにアクセスし、データをサーバからもらう
    • メリット
      • つくるのが簡単で、大体のことはRESTで事足りる
    • デメリット
      • クライアントがゲームから途中離脱した場合などの接続管理が面倒
      • サーバから自主的にデータを送ることはできない
  • WebSocket

    • ざっくり説明
      • 双方向通信用の通信方式
      • 接続が解除されるまではサーバとクライアントが常に通信を保ち、データのやり取りをする
    • メリット
      • クライアントがゲームから途中離脱した場合などの接続管理が簡単
      • サーバから自主的にデータを送ることができる
    • デメリット
      • 通信負荷とか、セキュリティとか考えるべき要素が増える
2
2
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
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?