この記事ではWebアプリケーションフレームワークのFlaskを使用した、チャット機能を紹介します。
今回は画像のようなチャットアプリケーションを作成します。
Flaskのインストールや基本的な使い方は以下の記事で紹介していますので、まだの方はご覧ください。
チャットアプリケーションの作り方
はじめに、今回作成するアプリケーションは、以下のディレクトリ構成になっています。
my_flask_app/
├── app.py
├── static/
│ └── styles.css
└── templates/
└── index.html
チャットアプリケーションを作成するために、リアルタイム通信を可能にするflask-socketioというパッケージをインストールします。
pip install flask-socketio
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flask Chat</title>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.0/socket.io.min.js"></script>
</head>
<body>
<div id="chat-container">
<div id="messages"></div>
<input id="message-input" autocomplete="off"><button onclick="sendMessage()">Send</button>
</div>
<script>
var socket = io();
socket.on('message', function(msg){
var messages = document.getElementById('messages');
var message = document.createElement('div');
message.classList.add('message', 'other');
message.textContent = msg;
messages.appendChild(message);
messages.scrollTop = messages.scrollHeight;
});
function sendMessage() {
var input = document.getElementById('message-input');
var msg = input.value;
if (msg.trim() === '') return;
// Add self message
var messages = document.getElementById('messages');
var message = document.createElement('div');
message.classList.add('message', 'self');
message.textContent = msg;
messages.appendChild(message);
messages.scrollTop = messages.scrollHeight;
// Send message to server
socket.emit('message', msg); // 修正: socket.sendからsocket.emitに変更
input.value = '';
}
</script>
</body>
</html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.0/socket.io.min.js"></script>
この部分で、Socket.IOというJavaScriptライブラリを外部のコンテンツ配信ネットワーク(Content Delivery Network, CDN)から直接ウェブページに読み込んでいます。
CDNを利用すると、ライブラリを自分のサーバーに置く必要がなく、外部の高速で信頼性の高いサーバーから直接提供されるため、ページの読み込み速度が向上します。
<script>
var socket = io();
socket.on('message', function(msg){
var messages = document.getElementById('messages');
var message = document.createElement('div');
message.classList.add('message', 'other');
message.textContent = msg;
messages.appendChild(message);
messages.scrollTop = messages.scrollHeight;
});
function sendMessage() {
var input = document.getElementById('message-input');
var msg = input.value;
if (msg.trim() === '') return;
// Add self message
var messages = document.getElementById('messages');
var message = document.createElement('div');
message.classList.add('message', 'self');
message.textContent = msg;
messages.appendChild(message);
messages.scrollTop = messages.scrollHeight;
// Send message to server
socket.emit('message', msg); // 修正: socket.sendからsocket.emitに変更
input.value = '';
}
</script>
この部分がJavaScriptです。どういう流れで処理をしているかだけ簡単に説明すると、
- Socket.IOを初期化して
socket
オブジェクトを作成 -
var socket = io();
の部分です。 - サーバーから受信したメッセージを処理するためのイベントリスナーを定義
-
socket.on('message', function(msg){ … });
の部分です。新しいメッセージを表示エリアに追加し、自動的にスクロールする設定にしています。 - メッセージ送信ボタンがクリックされた時に実行される関数を定義
-
sendMessage()
でメッセージ送信ボタンがクリックされた時の処理を実装しています。入力されたメッセージを取得して、サーバーに送信するということをしています。
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
@app.route('/')
def index():
return render_template('index.html')
@socketio.on('message')
def handleMessage(msg):
print('Message: ' + msg)
emit('message', msg, broadcast=True, include_self=False)
if __name__ == '__main__':
socketio.run(app)
@socketio.on('message')
def handleMessage(msg):
print('Message: ' + msg)
emit('message', msg, broadcast=True, include_self=False)
この部分でメッセージハンドラを定義しています。クライアントから'message'
イベントが送信されたときに、この関数が実行され、print('Message: ' + msg)
で、受信したメッセージをサーバーのコンソールに出力します。
emit('message', msg, broadcast=True, include_self=False)
を行うことで、受信したメッセージを他の全てのクライアントに送信しています。
#chat-container {
display: flex;
flex-direction: column;
align-items: stretch;
width: 300px;
margin: 0 auto;
}
#messages {
border: 1px solid #ccc;
padding: 10px;
height: 300px;
overflow-y: scroll;
width: 100%;
margin-bottom: 10px;
display: flex;
flex-direction: column;
}
.message {
display: inline-block;
padding: 10px;
border-radius: 10px;
margin-bottom: 10px;
max-width: 80%;
word-wrap: break-word;
}
.message.self {
background-color: #007BFF;
color: white;
align-self: flex-start;
}
.message.other {
background-color: #e5e5ea;
align-self: flex-end;
}
実行結果
実行すると、以下のようなチャット画面が表示されます。
適当なメッセージを入力して送信してみます。
別のタブでもう一つ開いてメッセージを送信してみます。
一つ目の画面に相手からのメッセージが表示されることが確認できます。