专栏
天翼云开发者社区

在KOA中建立共享会话的WebSocket链接

前端

Javascript

Nodejs

2023-04-14 14:27:33 15阅读

概念介绍

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链接中进行更加复杂的业务处理。

    • 0
    • 0
    • 0
    0 评论