記事概要
FlaskでWebSoket通信を利用して、簡易なチャットアプリのサンプルを作成する。
スクリプト
Server
from flask import Flask, request, render_template, send_from_directory
from flask_socketio import SocketIO, emit
from flask_cors import CORS
app = Flask(__name__, static_folder='static', static_url_path='/')
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app, cors_allowed_origins="*")
CORS(app, supports_credentials=True, responses={r"/*": {"origins": "*"}})
@app.route('/')
def index():
# return send_from_directory('static', 'index.html') # staticフォルダのindex.html
return render_template('index.html') # templateフォルダのindex.html
@app.route('/<path:filename>')
def serve_static(filename):
return send_from_directory('static', filename)
@socketio.on('message', namespace='/demo')
def handle_message(message):
emit('message', f'{request.sid} => {message}', namespace='/demo', broadcast=True)
if __name__ == '__main__':
socketio.run(app, host='0.0.0.0', port=5002, debug=True)
Client
<!DOCTYPE html>
<html>
<head>
<title>WebSocket Chat</title>
</head>
<body>
<input id="message_input" autocomplete="off" /><button id="send">Send</button>
<ul id="messages"></ul>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
<script type="text/javascript">
const socket = io.connect('/demo')
socket.on('message', (data) => {
console.log('message', data)
const li = document.createElement('li')
li.appendChild(document.createTextNode(data))
document.getElementById('messages').appendChild(li)
})
document.getElementById('send').addEventListener('click', (e) => {
const message_input = document.getElementById('message_input')
const message = message_input.value
socket.emit('message', message)
message_input.value = ''
})
document.getElementById('message_input').addEventListener('keydown', (e) => {
if (e.keyCode === 13) {
const message_input = document.getElementById('message_input')
const message = message_input.value
socket.emit('message', message)
message_input.value = ''
}
})
</script>
</body>
</html>
使い方
- 上記コードではポート5002で立ち上げて、別IPからもWebSoket通信が行えるようにCORSを使っている。
- 静的ファイルの置き場として、staticフォルダを指定している。
- Clientはpythonファイルと同じ階層に
templates
フォルダを作成して、その中にindex.html
を作る。
emit('message', f'{request.sid} => {message}', namespace='/demo', broadcast=True)
⇑このようにメッセージ送信を行っているが、ルームを指定することで、個別にMessageのやり取りをすることが出来る。
emit('message', f'{request.sid} => {message}', namespace='/demo', broadcast=True, room='hoge')