Flask 網路套接字
通過這個解釋,我們將瞭解 WebSocket 是什麼以及它是如何在客戶端和伺服器之間工作的。我們還將學習如何藉助 Flask 中的 flask_socketio 模組製作一個實時聊天應用程式。
藉助 Flask 中的 flask_socketio
WebSocket 建立實時應用程式
WebSocket 是一種在客戶端和伺服器之間開啟套接字的方法。使用 WebSockets,我們可以實時傳送訊息。
它不是典型的網路請求-響應模型;就像一個開放的連線永遠存在,伺服器和客戶端可以不斷地相互對話。
現在讓我們構建聊天應用程式;我們將處理的第一方面是伺服器端。有兩個方面:第一個是伺服器端,它將由 Flask 處理,第二個是客戶端,它將由 JavaScript 處理。
擴充套件 flask_socketio
允許客戶端與伺服器連線,因此我們需要使用以下命令安裝 flask_socketio
模組。
pip install Flask-SocketIO
它將安裝 flask_socketio
以及它需要的任何依賴項。flask_socketio
與典型的 Flask 應用程式非常相似,模式相同,但我們使用的一些東西略有不同。
我們將匯入一些類和 send
函式來構建這個應用程式。然後我們將建立一個應用程式例項,由於所有訊息都是加密的,我們需要金鑰;我們將金鑰定義為 config
值。
現在我們將為 SocketIO()
類建立一個物件並通過傳遞應用程式來例項化它,第二個引數是允許所有域。
app.config['SECRET_KEY'] = 'ffff111jjj52'
socketio = SocketIO(app, cors_allowed_origins='*')
現在我們將定義一個路由來監聽我們在路由中指定的特定事件,然後我們將建立一個函式,當我們傳送函式名稱為 Text_MSG()
的訊息時將呼叫該函式。
這個函式接受一個名為 msg
的引數,我們將把它列印出來以確保控制檯上的一切正常。
我們將接收來自任何人的訊息,並將其傳送給當時連線到伺服器的每個人。我們將使用 send()
函式,該函式將採用兩個引數:一個是 msg
,它是一條文字訊息,第二個是一個 broadcast
,它等於 True
。
如果我們將 False
傳遞給 broadcast
或不傳遞此引數,那麼它將預設將訊息傳送給我們首先從那裡獲得訊息的任何人。
由於我們正在廣播併傳送我們從一個客戶端收到的相同訊息,因此我們會將其傳送回所有客戶端,包括我們剛剛收到它的客戶端。
@socketio.on('message')
def Text_MSG(msg):
print('text-message: ' + msg)
send(msg, broadcast=True)
我們將不使用 app.run()
,而是使用 socketio.run(app)
,它具有在實時環境中執行 Flask 應用程式的額外功能。
if __name__ == '__main__':
socketio.run(app)
讓我們進入前端的建築物,它將是一個 HTML 頁面。我們將從 CDN 為客戶端 socket.io
庫匯入幾個指令碼。我們還將使用 jQuery 來處理按鈕上的單擊事件。
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.8/socket.io.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
在 body
標籤中,我們將編寫 JavaScript 程式碼。因為我們使用的是 jQuery,所以我們必須使用 ready()
方法,並且在這個 $(document).ready()
中,我們需要連線到執行 Flask 應用程式的伺服器。
我們將建立一個名為 socket
的物件並使用 connect()
對其進行例項化,並將 URL 傳遞給 Flask 伺服器。一旦我們建立了一個物件,我們需要確保當我們連線到伺服器時,我們可以向它傳送訊息。
$(document).ready(function() {
var socket = io.connect('http://127.0.0.1:5000');
socket.on('connect', function() {
socket.send('User has connected!');
});
});
這意味著我們正在監聽一個特定的事件,並且每當我們第一次連線到伺服器時都會發生連線事件,一旦發生,它就會呼叫這個 socket.on()
回撥函式。這個回撥函式會傳送給使用者已經連線的伺服器,伺服器將讀取它併傳送給每個人。
讓我們新增程式碼來映象傳送到伺服器的任何訊息,以便我們將偵聽另一個事件而不是 connect
。message
回撥函式會將訊息附加到我們的訊息列表中,我們還將使用訊息文字固定一個列表項。
socket.on('message', function(msg) {
$("#messages").append('<li>'+msg+'</li>');
console.log('Received message');
});
我們要做的最後一件事是允許使用按鈕傳送訊息。因此,我們將在傳送按鈕上放置一個點選事件,並將 myMessage
id 與 input
標籤 id 附加在一起。
一旦我們傳送它,我們將使用 val('')
方法清除我們的訊息以便為新訊息騰出空間。
$('#sendbutton').on('click', function() {
socket.send($('#myMessage').val());
$('#myMessage').val('');
});
現在我們將儲存它並執行 Flask 伺服器,然後我們將在兩個視窗中開啟一個 index.html
檔案。當我們在輸入欄位中輸入一些文字並點選傳送
按鈕時,我們將同時在另一個視窗中接收訊息。
注意:如果出現錯誤,請在終端中執行以下命令。
pip install --upgrade python-socketio==4.6.0
pip install --upgrade python-engineio==3.13.2
pip install --upgrade Flask-SocketIO==4.3.1
完整的 Python 程式碼:
from flask import Flask
from flask_socketio import SocketIO, send
app = Flask(__name__)
app.config['SECRET_KEY'] = 'ffff111jjj52'
socketio = SocketIO(app, cors_allowed_origins='*')
@socketio.on('message')
def Text_MSG(msg):
print('text-message: ' + msg)
send(msg, broadcast=True)
if __name__ == '__main__':
socketio.run(app)
完整的 HTML 程式碼:
<html>
<head>
<title>Chat Room</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.8/socket.io.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
$(document).ready(function() {
var socket = io.connect('http://127.0.0.1:5000');
socket.on('connect', function() {
socket.send('User has connected!');
});
socket.on('message', function(msg) {
$("#messages").append('<li>'+msg+'</li>');
console.log('Received message');
});
$('#sendbutton').on('click', function() {
socket.send($('#myMessage').val());
$('#myMessage').val('');
});
});
</script>
<ul id="messages"></ul>
<input type="text" id="myMessage">
<button id="sendbutton">Send</button>
</body>
</html>
Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.
LinkedIn