On this page
连接websocket和权限验证
具体看课程演示
js
// app/router.js
app.ws.use(async (ctx, next) => {
// 获取参数 ws://localhost:7001/ws?token=123456
// ctx.query.token
// 验证用户token
let user = {};
let token = ctx.query.token;
try {
user = ctx.checkToken(token);
// 验证用户状态
let userCheck = await app.model.User.findByPk(user.id);
if (!userCheck) {
ctx.websocket.send(JSON.stringify({
msg: "fail",
data: "用户不存在",
}));
return ctx.websocket.close();
}
if (!userCheck.status) {
ctx.websocket.send(JSON.stringify({
msg: "fail",
data: "你已被禁用",
}));
return ctx.websocket.close();
}
// 用户上线
app.ws.user = app.ws.user ? app.ws.user : {};
// 下线其他设备
if (app.ws.user[user.id]) {
app.ws.user[user.id].send(JSON.stringify({
msg: "fail",
data: "你的账号在其他设备登录",
}));
app.ws.user[user.id].close();
}
// 记录当前用户id
ctx.websocket.user_id = user.id;
app.ws.user[user.id] = ctx.websocket;
await next();
} catch (err) {
console.log(err);
let fail = err.name === "TokenExpiredError"
? "token 已过期! 请重新获取令牌"
: "Token 令牌不合法!";
ctx.websocket.send(JSON.stringify({
msg: "fail",
data: fail,
}));
// 关闭连接
ctx.websocket.close();
}
});
// 路由配置
app.ws.route("/ws", controller.chat.connect);
js
// app/controller/chat.js
const Controller = require("egg").Controller;
class ChatController extends Controller {
// 连接socket
async connect() {
const { ctx, app } = this;
if (!ctx.websocket) {
ctx.throw(400, "非法访问");
}
// console.log(`clients: ${app.ws.clients.size}`);
// 监听接收消息和关闭socket
ctx.websocket
.on("message", (msg) => {
// console.log('接收消息', msg);
})
.on("close", (code, reason) => {
// 用户下线
console.log("用户下线", code, reason);
let user_id = ctx.websocket.user_id;
if (app.ws.user && app.ws.user[user_id]) {
delete app.ws.user[user_id];
}
});
}
}
module.exports = ChatController;