Flaskを使ったWebSocketについて、とても参考になるサイトを見つけましたので試してみました。
環境) Python 3.9.6 / Mac(arm64)
Flask==3.0.0
Flask-SocketIO==5.3.6
メモ)
Windowsで動かした時、geventモジュールのエラーが出ました。
また、allow_unsafe_werkzeug=True が必要のようです。
参考)
https://wonderhorn.net/programming/flaskwebsocket.html
JavaScriptコードがあるhtmlファイルをstaticフォルダにおきました。
static/index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<html> <body> <script src="socket.io.js"></script> <script type="text/javascript" charset="utf-8"> var socket = io(); function ping(){ t = new Date(); socket.emit('ping', {ping_time: t.getTime()}); document.getElementById("log").innerHTML += ('ping: ' + t.getTime() + "<br>"); } socket.on('connect', function() { socket.on('pong', (msg) => { t = new Date(); document.getElementById("log").innerHTML += ('pong: ' + t.getTime() + ' / ' + msg + "<br>"); }); //ping(); }); </script> <button type="button" onclick="ping();"> Ping </button> <div id="log"></div> </body> </html> |
websock.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
from flask import Flask from flask_socketio import SocketIO, send, emit import time app = Flask(__name__) sio = SocketIO(app) @sio.on("ping") def ping(data): print(data) print(time.time()) for i in range(5): time.sleep(1) emit("pong", str(i+1)) @app.route("/") def index(): script = """ <h3>Hello!</h3> <a href=/static/index.html>WebSocket Test</a> """ return script if __name__ == "__main__": sio.run(app, host="127.0.0.1", port=5000, allow_unsafe_werkzeug=True) |
WebSocketとHTTPのサーバが同じファイルに記述できることを確認できます。
起動
% python websock.py
今回確認したかった、1秒ごとにpongが順に表示されることですが、複数ブラウザを立ち上げて同時に実行しても問題なく動作しました。
また内容の確認のためにも、socket.io.jsはダウンロードしてローカルに置いてみました。
socket.io.js (長いので先頭の一部分 185009byte)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
/*! * Socket.IO v4.0.1 * (c) 2014-2021 Guillermo Rauch * Released under the MIT License. */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["io"] = factory(); else root["io"] = factory(); })(self, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } ... ... |