概念介绍
WebSocket链接区别于http协议,他是位于TCP上层的全双工的协议,也就是说服务端可以主动的推送消息给客户端。在一些实时更新数据的场景中比较适用。
koa是nodejs中较为流行服务端框架,经常被用来作为http服务端开发使用,本文就简单介绍一下在koa框架下如何建立WebSocket链接,并且能够在wss链接中获取并使用http服务器中的会话信息。
基础工具介绍
首先介绍一下我们在项目中使用的一些库。
- 用户会话管理中间件koa-session
- ws的nodejs库ws
- ws设置外部http服务器所需模块http
我们使用koa-session来对用户的会话信息进行管理,然后将koa作为外部的http服务器,将wss链接和http的服务域做成一致的。然后在wss链接中获取用户会话信息进行业务操作。
实施细节
1. 配置会话
我们创建koa服务器实例之后,使用koa-session的中间件进行管理,具体如下
const Koa = require('koa');
const app = new Koa();
const session = require('koa-session');
const CONFIG = {
// 具体配置
};
app.use(session(CONFIG, app));
2. wss服务器使用外部http服务器
ws可以创建ws的服务器,使用区别于http的端口和路径,为了复用http的端口,ws需要配置额外的服务器。如下:
const http = require('http'); // 如果是https则引入https模块
const server = http.createServer(app.callback()); // app是koa的服务器实例
const wss = new WebSocket.Server({ clientTracking: false, noServer: true }); //不使用自身的server,使用外部http服务器
3. 在ws链接中获取用户会话信息
在外部的http服务器中监听ws链接,并识别用户会话信息,然后再处理后续业务。
server.on('upgrade', function (request, socket, head) {
// console.log('Parsing session from request...');
const context = app.createContext(request, {});
// context.session里面就是上下文的会话信息。可以用来识别用户是否登录
if (!context.session.isLoggedIn) {
console.log('尚未登录,请先登录');
socket.destroy();
return;
}
wss.handleUpgrade(request, socket, head, function (ws) {
wss.emit('connection', ws, request);
});
});
wss.on('connection', function connection(ws, request) {
const context = app.createContext(request, {});
ws.on('message', function incoming(e) {
// 接收到message,然后进行业务处理
});
});
主要的核心就是koa的app提供一个由request来获取上下文信息的接口。即 app.createContext(requst, {})。在request里面有客户端发送请求时携带的cookie信息。app就可以基于cookie获取用户的上下文会话。
总结
本文主要描述了如何实施wss服务器使用koa作为外部的http服务器,复用http的端口,然后在ws的链接中获取上下文会话信息。其核心有两个,1是在创建ws服务器时配置使用外部的http服务器,2是在ws链接中使用app的createContext接口获取客户端上下文会话。
复用http端口的好处是客户端新建wss链接时不需要考虑跨域,而且可以获取用户的会话信息,在ws链接中进行更加复杂的业务处理。