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