Flask-SocketIO 是一個基于 Flask 和 Socket.IO 的 Python Web 應用程式開發庫。它使得在 Flask 應用中使用實時 Web 功能變得非常容易。
Socket.IO 是一個 JavaScript 庫,它允許雙向實時通信。它基于 WebSockets,但是也提供了向後相容的輪詢等技術,以支援所有 Web 浏覽器。
Flask-SocketIO 提供了許多有用的功能,例如:
- 基于事件的消息通信,可以向特定的用戶端或所有用戶端廣播消息
- 基于 Flask 視圖的 Socket.IO 端點
- Flask-SocketIO 內建了 Werkzeug 的 HTTP 基礎設施,這使得使用 Flask-SocketIO 的應用程式具有很高的性能和可擴充性
下面是一個使用 Flask-SocketIO 的簡單示例:
pythonCopy codefrom flask import Flask
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
@socketio.on('connect')
def handle_connect():
print('client connected')
@socketio.on('message')
def handle_message(data):
print('received message:', data)
emit('response', 'hello from server')
if __name__ == '__main__':
socketio.run(app)
在用戶端連接配接到伺服器時,會自動觸發 connect 事件。通過 on 方法注冊事件處理函數,可以在伺服器端處理用戶端發送的事件。使用 emit 方法可以向用戶端發送消息。
在用戶端使用 JavaScript 來處理事件,示例如下:
javascriptCopy codevar socket = io.connect('http://localhost:5000');
socket.on('connect', function() {
console.log('connected to server');
});
socket.on('response', function(data) {
console.log('received response:', data);
});
socket.emit('message', 'hello from client');
在用戶端連接配接到伺服器時,會自動觸發 connect 事件。使用 on 方法注冊事件處理函數,可以在用戶端處理伺服器發送的事件。使用 emit 方法可以向伺服器發送消息。
使用 Flask-SocketIO 可以輕松地實作實時 Web 功能。與 Flask-SocketIO 一起使用的 Socket.IO 還提供了許多其他功能,例如房間、命名空間等。
下面是一個簡單的聊天室示例,使用 Flask-SocketIO 實作。
server.py:
pythonCopy codefrom flask import Flask, render_template
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
# 儲存線上使用者
online_users = set()
@app.route('/')
def index():
return render_template('index.html')
# 接收用戶端發送的消息
@socketio.on('message')
def handle_message(data):
emit('broadcast', data, broadcast=True)
# 使用者上線
@socketio.on('login')
def handle_login(username):
# 将使用者添加到線上使用者集合
online_users.add(username)
emit('user_list', list(online_users), broadcast=True)
emit('broadcast', f'{username} has joined the chat', broadcast=True)
# 使用者下線
@socketio.on('logout')
def handle_logout(username):
# 将使用者從線上使用者集合中移除
online_users.remove(username)
emit('user_list', list(online_users), broadcast=True)
emit('broadcast', f'{username} has left the chat', broadcast=True)
if __name__ == '__main__':
socketio.run(app)
templates/index.html:
templates/index.html:
htmlCopy code<!doctype html>
<html>
<head>
<title>Chat Room</title>
<script src="https://cdn.socket.io/4.4.1/socket.io.min.js" integrity="sha384-+7Vh13f86uA7bflvRj83M7hPG/E17FtwupV7q3Un19/0VfYQOxFh/7xNcE0RIs1" crossorigin="anonymous"></script>
<script src="//code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Chat Room</h1>
<div id="message-list"></div>
<div>
<input type="text" id="username" placeholder="Your Name">
<button id="login-btn">Login</button>
<button id="logout-btn" disabled>Logout</button>
</div>
<div>
<input type="text" id="message" placeholder="Your Message">
<button id="send-btn" disabled>Send</button>
</div>
<div id="user-list"></div>
<script>
$(function() {
var socket = io();
var username = '';
// 顯示線上使用者清單
function showUserList(users) {
var html = '<h3>Online Users:</h3><ul>';
users.forEach(function(user) {
html += '<li>' + user + '</li>';
});
html += '</ul>';
$('#user-list').html(html);
}
// 顯示聊天記錄
function showMessageList(message) {
$('#message-list').append($('<p>').text(message));
}
// 登入按鈕事件處理函數
$('#login-btn').click(function() {
username = $('#username').val();
socket.emit('login', username);
$('#username').val('');
$('#username').attr('disabled', 'disabled');
$('#login-btn').attr('disabled', 'disabled');
$('#logout-btn').removeAttr('disabled');
$('#send-btn').removeAttr('disabled');
});
// 登出按鈕事件處理函數
$('#logout-btn').click(function() {
socket.emit('logout', username);
$('#message-list'). empty();
$('#username').removeAttr('disabled');
$('#login-btn').removeAttr('disabled');
$('#logout-btn').attr('disabled', 'disabled');
$('#send-btn').attr('disabled', 'disabled');
username = '';
});
// 發送消息按鈕事件處理函數
$('#send-btn').click(function() {
var message = $('#message').val();
socket.emit('message', '[' + username + '] ' + message);
$('#message').val('');
});
// 顯示線上使用者清單
socket.on('user_list', function(users) {
showUserList(users);
});
// 顯示聊天記錄
socket.on('broadcast', function(message) {
showMessageList(message);
});
});
</script>
</body>
</html>
在終端中運作 python server.py 啟動服務端,然後在浏覽器中通路 http://localhost:5000 即可進入聊天室。
該示例中,通過 emit 方法向用戶端發送消息,通過 on 方法接收用戶端發送的消息。broadcast 參數表示将消息廣播給所有用戶端。
此外,還通過 online_users 集合儲存線上使用者清單,并在使用者登入、登出時更新使用者清單。