Eggjs学习系列(六) Socket.IO实践

本文介绍了如何在Eggjs项目中使用Socket.IO进行实时通信,包括安装配置、使用redis、基本使用方法、控制器和中间件的设置,以及如何处理命名空间和事件。文章还提到了在Cluster模式下启用sticky支持的重要性,并提供了前端连接的示例。
摘要由CSDN通过智能技术生成

Eggjs学习系列(六) Socket.IO实践

Socket.IO 是一个基于 Node.js 的实时应用程序框架,在即时通讯、通知与消息推送,实时分析等场景中有较为广泛的应用。

Eggjs提供了 egg-socket.io插件来实现 websocket 通信,并增加了下列开发规约:

  • namespace: 通过配置的方式定义 namespace(命名空间)
  • middleware: 对每一次 socket 连接的建立/断开、每一次消息/数据传递进行预处理
  • controller: 响应 socket.io 的 event 事件
  • router: 统一了 socket.io 的 event 与 框架路由的处理配置方式

安装和配置

npm i egg-socket.io --save

开启插件

// app/config/plugin.ts
import {
    EggPlugin } from 'egg';
const plugin: EggPlugin = {
   
  // static: true,
  io: {
   
    enable: true,
    package: 'egg-socket.io',
  },
};
export default plugin;

添加配置

// app/config/config.default.ts
import {
    EggAppConfig, EggAppInfo, PowerPartial } from 'egg';
export default (appInfo: EggAppInfo) => {
   
    const config = {
   } as PowerPartial<EggAppConfig>;
    // add your special config in here
    const bizConfig = {
   
        io: {
   
            init: {
   }, // 设置引擎, 默认 ws 引擎
            namespace: {
   
                // namespace(nsp) 通常意味分配到不同的接入点或者路径。
            	// 如果客户端没有指定 nsp,则默认分配到 `/` 这个默认的命名空间。
                '/io': {
   
                    connectionMiddleware: [],
                    packetMiddleware: [],
                },
            },
        },
    };

    // the return config will combines to EggAppConfig
    return {
   
        ...config,
        ...bizConfig
    };
};

使用 redis

egg-socket.io内置了socket.io-redis,可在 cluster 模式下,使用 redis 实现信息共享

// app/config/config.default.ts
const bizConfig = {
   
    io: {
   
        init: {
   }, // 设置引擎, 默认 ws 引擎
        namespace: {
   
            // namespace(nsp) 通常意味分配到不同的接入点或者路径。
            // 如果客户端没有指定 nsp,则默认分配到 `/` 这个默认的命名空间。
            '/io': {
   
                connectionMiddleware: [],
                packetMiddleware: [],
            },
        },
        // 配置 redis
        redis: {
   
            host: '127.0.0.1',
            port: 6379,
        },
    },
};

注意:

框架是以 Cluster 方式启动的,而 socket.io 协议实现需要 sticky 特性支持,否则在多进程模式下无法正常工作。 需要在启动命令添加 sticky 参数:

{
   
  "scripts": {
   
    "dev": "egg-bin dev --sticky",
    "start": "egg-scripts start --sticky"
  }
}

基本使用

app 目录下创建 io 用于存放 socket 相关代码

为了使用 Typescript 中的智能提示功能,需要在 index.d.ts 中引入 egg-socket.io

// typings/index.d.ts
import 'egg-socket.io'

引入之后,会发现使用 app.io 等的时候会有代码提示。为了能够使用 socket.io 的智能提示,还需要再安装

yarn add @types/socket.io

首先在 helper 中添加函数,用于封装 socket 交互的基本数据格式

// app/extend/helper.ts
// 添加扩展
export default {
   
    /**
   * 封装 socket 请求数据格式
   * @param action 事件
   * @param payload 数据
   * @param metadata 元信息
   */
    parseMsg(action, payload = {
   }, metadata = {
   }) {
   
        // 封装 meta 数据,添加当前时间轴
        const meta = Object.assign({
   }, {
   
            timestamp: Date.now(),
        }, metadata);
        // 格式化返回数据
        return {
   
            meta,
            data: {
   
                action,
                payload,
            },
        };
    },
};

Middleware

接下来在 middleware 中间件中处理 socket 连接。

注意: socket 中间件位于 app/io/middleware 目录下,用于处理 socket.io 的请求。

// app/io/middleware/auth.ts
import {
    Context } from 'egg';
const PREFIX = 'room';

export default function AuthMiddleware() {
   
  return async (ctx: Context, next: () => Promise<any>) => {
   
    const {
    app, socket, logger, helper <
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值