MENU

【初心者向けWebサイト開発】Flaskでチャットアプリケーションを作成する

この記事ではWebアプリケーションフレームワークのFlaskを使用した、チャット機能を紹介します。

今回は画像のようなチャットアプリケーションを作成します。

Flaskのインストールや基本的な使い方は以下の記事で紹介していますので、まだの方はご覧ください。

目次

チャットアプリケーションの作り方

はじめに、今回作成するアプリケーションは、以下のディレクトリ構成になっています。

my_flask_app/
├── app.py
├── static/
│   └── styles.css
└── templates/
    └── index.html
STEP
必要なパッケージのインストール

チャットアプリケーションを作成するために、リアルタイム通信を可能にするflask-socketioというパッケージをインストールします。

pip install flask-socketio
STEP
HTML(templates/index.html)の編集
<!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()でメッセージ送信ボタンがクリックされた時の処理を実装しています。入力されたメッセージを取得して、サーバーに送信するということをしています。

STEP
app.pyの編集
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)を行うことで、受信したメッセージを他の全てのクライアントに送信しています。

STEP
CSS(static/styles.css)の編集
#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;
}

実行結果

実行すると、以下のようなチャット画面が表示されます。

適当なメッセージを入力して送信してみます。

別のタブでもう一つ開いてメッセージを送信してみます。

一つ目の画面に相手からのメッセージが表示されることが確認できます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

20代の組み込みソフトウェアエンジニア
主な使用言語はC++

---------------------資格---------------------
応用情報技術者
ネットワークスペシャリスト

目次