python
web
Socket.IOとはWebSocketプロトコルを実装した 複数言語対応のライブラリだ。JavaScriptも、PythonにてWebフレームワークFlaskに 組み込んだFlask-SocketIO もあるのでFlaskベースのWebアプリにはもってこいである。
FlaskとFlask-SocketIOを利用したミニマムなサンプルコードを書いた。ここではいわゆるpingpongを例として実装した。
動作は
- ぺージ読み込み完了時にソケットを張る
- クライアントがボタンを押すと"ping"がサーバ側に飛ぶ
- サーバは"ping"が来たら"pong"と打ち返す
ポイントとしてはWebSocketの通信がイベントとしてやり取りされる点だ。
Pythonサーバ側では
@sio.on("ping")
で修飾された関数が
"ping"というイベントに紐づけられる(イベント名は何でもよい)。
これをクライアント側からsocket.emit('ping', {data: "hoge"}
のように
WebSocketデータを投げつけることで発火させることができる。
このようにJavaScriptではよくあるイベント駆動型のプログラミングとWebSocketは相性がよい。
from flask import Flask from flask_socketio import SocketIO, send, emit import time app = Flask(__name__) sio = SocketIO(app) # socketを初期化 @sio.on("ping") # pingイベントが届いたら呼ばれるコールバック def ping(data): print(data) print(time.time()) emit("pong", str(time.time())) @app.route("/") # これはただのFlaskエンドポイント def index(): # 1ファイルで済ませるためjsを直書き script = """ <!--JSのSocket.IOクライアントを読み込む--> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script> <script type="text/javascript" charset="utf-8"> var socket = io(); function ping(){ t = new Date(); socket.emit('ping', {data: t.getTime()}); // サーバにpingイベントを投げつける document.getElementById("log").innerHTML += ('ping: ' + t.getTime() + "<br>"); } socket.on('connect', function() { // 初期化時に呼ばれるコールバック socket.on('pong', (msg) => { // pongが帰ってきたら呼ばれるコールバック t = new Date(); document.getElementById("log").innerHTML += ('pong: ' + t.getTime() + "<br>"); }); //ping(); }); </script> <button type="button" onclick="ping();"> Ping </button> <div id="log"></div> """ return script if __name__ =="__main__": sio.run(app, host="0.0.0.0", port=5001)
これを
python main.py
で立ち上げたままブラウザでlocalhost:5001
にアクセスすることで試すことができる。
スクリーンショット

動作確認したバージョン
- Python 3.7.2
- Flask==1.1.2
- Flask-SocketIO==5.1.0