连接和取消连接
在进入首页后,我们要做的第一件事就是连接上 WebSocket。Flask-SocketIO 是通过事件的形式进行通信的,Flask-SocketIO 默认内置了许多事件,其中最常用的就是 connect 和 disconnect。我们先在服务端实现 connect 事件,代码如下。
from flask_socketio import SocketIO, emit
@socketio.on('connect')
@login_required
def connect():
print("连接成功")
UserManager.add_user(session.get("username"), request.sid)
emit("users", {"users": UserManager.all_username()}, broadcast=True)
上述代码中,我们通过 @socketio.on 来设置事件发生后的执行函数,这里定义的是 connect 事件。客户端在连接 connect 事件后,先把当前用户存储在 UserManager 中,在存储用户信息时,把用户名以及当前用户的 Session ID 也就是 request.sid 都存放进去,然后再通过 emit 函数发送一个 users 事件,有新用户登录后,我们要通知所有已连接用户,所以设置 broadcast=True,也就是采用广播的方式进行发送。接下来,在客户端中使用 JavaScript SocketIO 库发送 connect 事件,代码如下。
const socket = io();
socket.on("connect", function() {
console.log("连接成功");
});
在浏览器中访问 http://127.0.0.1:5000/ 后,如果控制台打印了 “连接成功”,则说明客户端和服务端已经完成握手,实现了长连接,后续可以通过其他事件来实现客户端和服务端的双向通信。
在浏览器被关闭后,应该主动断开连接。服务端在收到断开连接事件后,应把当前用户从 UserManager 中移除,并广播给其他用户,代码如下。
@socketio.on("disconnect")
@login_required
def disconnect():
UserManager.remove_user(session.get('username'))
emit("users", {"users": UserManager.all_username()}, broadcast=True)
接下来,在浏览器端监听页面的关闭事件,在关闭之前先发送 disconnect 事件,代码如下。
$(window).bind("beforeunload", function () {
socket.on("disconnect");
});
上述代码中,我们使用了 jQuery 的事件绑定方式,对 beforeunload 事件进行了绑定,在发生此事件后,主动向服务器发送 disconnect 事件。