npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@cabloy/egg-socket.io

v6.0.0

Published

egg plugin for socket.io

Downloads

50

Readme

egg-socket.io

NPM version build status Test coverage David deps Known Vulnerabilities npm download

egg 框架的 socket.io 插件

安装

$ npm i egg-socket.io --save

环境要求

  • Node.js >= 8.0
  • Egg.js >= 2.0

配置

通过 config/plugin.js 配置启动 Socket.IO 插件:

// {app_root}/config/plugin.js
exports.io = {
  enable: true,
  package: 'egg-socket.io',
};

config/config.${env}.js 配置 Socket.IO :

exports.io = {
  init: { }, // passed to engine.io
  namespace: {
    '/': {
      connectionMiddleware: [],
      packetMiddleware: [],
    },
  },
  redis: {
    host: '127.0.0.1',
    port: 6379
  }
};

uws

Egg Socket 内部默认使用 ws 引擎,uws 因为某些原因被废止。

如坚持需要使用,请按照以下配置即可:

exports.io = {
  init: { wsEngine: 'uws' },
};
  • 有关更多 init 选项配置,请参考:engine.io
  • 有关更多 Egg Socket 相关默认配置,请参考:config.default.js

generateId

注意: 此函数作为接口预留,便于你按照自己的规则为每一个 socket 生成唯一的 ID:

exports.io = {
  generateId: (request) => {
        // Something like UUID.
        return 'This should be a random unique ID';
    }
};

部署

Node 配置

由于 Socket.IO 的设计缘故,多进程的 Socket.IO 服务必须在 sticky 模式下才能工作,否则会抛出握手异常。

所以,必须开启 sticky 模式:

$ # 修改 package.json 对应的 npm scripts
$ egg-bin dev --sticky
$ egg-scripts start --sticky

这两个脚本都会使框架启动 cluster 时使用 sticky 模式

startCluster({
  sticky: true,
  ...
});

Nginx 配置

如果你使用了 nginx 做代理转发:

location / {
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_pass   http://127.0.0.1:{ your node server port };
}

用法

目录结构

app
├── io
│   ├── controller
│   │   └── chat.js
│   └── middleware
│       ├── auth.js
│       ├── filter.js
├── router.js
config
 ├── config.default.js
 └── plugin.js

中间件

middleware are functions which every connection or packet will be processed by.

连接中间件

  • 编写连接中间件 app/io/middleware/auth.js
module.exports = app => {
    return async (ctx, next) => {
        ctx.socket.emit('res', 'connected!');
        await next();
        // execute when disconnect.
        console.log('disconnection!');
    };
};
  • 配置使之生效

config/config.default.js

exports.io = {
  namespace: {
    '/': {
      connectionMiddleware: ['auth'],
    },
  },
};

注意,必须配置在特定的命名空间下,才会生效

包中间件

  • 编写包中间件 app/io/middleware/filter.js
module.exports = app => {
    return async (ctx, next) => {
        ctx.socket.emit('res', 'packet received!');
        console.log('packet:', this.packet);
        await next();
    };
};
  • 配置使之生效

config/config.default.js

exports.io = {
  namespace: {
    '/': {
      packetMiddleware: ['filter'],
    },
  },
};

注意,必须配置在特定的命名空间下,才会生效

控制器

controller is designed to handle the emit event from the client.

example:

app/io/controller/chat.js

module.exports = app => {
  class Controller extends app.Controller {
    async ping() {
      const message = this.ctx.args[0];
      await this.ctx.socket.emit('res', `Hi! I've got your message: ${message}`);
    }
  }
  return Controller
};

// or async functions
exports.ping = async function() {
  const message = this.args[0];
  await this.socket.emit('res', `Hi! I've got your message: ${message}`);
};

下一步,在 app/router.js 配置路由

module.exports = app => {
  // or app.io.of('/')
  app.io.route('chat', app.io.controller.chat.ping);
};

路由

路由主要负责对特定的 socket 连接不同的事件进行分发处理到对应的控制器。路由配置写在 app/router.js 中,实例参照上一节。

除了,业务逻辑的路由之外,还有配置几个系统内置事件:

  • disconnecting 正在断开连接
  • disconnect 连接已经断开
  • error 发生了错误

示例:

app/router.js

app.io.route('disconnect', app.io.controller.chat.disconnect);

app/io/controller/chat.js

module.exports = (app) => {
  class Controller extends app.Controller {
    async disconnect() {
      const message = this.ctx.args[0];
      console.log(message);
    }
  }
  return Controller
};

会话

egg-socket.io 支持会话,与普通的 HTTP 会话几乎一样。

会话的创建和鉴权只发生在建立连接阶段。在包中间件和控制器中可以获取通过 ctx.session 获取会话对象,但是它只在连接创建。

会话功能由 egg-session 实现,请确保它已经开启。

集群

如果你的 Socket.IO 服务由多台服务器提供,那么必须思考集群方案。比如,广播,房间等功能,必须依赖集群方案。

egg-socket.io 集成了 socket.io-redis ,能够非常方便的实现集群共享资源与事件分发。

配置起来也很简单:

只需要在 config/config.${env}.js 配置 :

exports.io = {
  redis: {
    host: { redis server host },
    port: { redis server prot },
    auth_pass: { redis server password },
    db: 0,
  }
};

egg 服务在启动时,会尝试连接 redis 服务,成功后,应用会顺利启动。

应用于微信小程序服务端

微信小程序所采用的 WebSocket 协议版本为 13 (可抓包查看),而 socket.io 支持的协议版本为 4 详见 socket.io-protocol

解决方案是可以封装一个适配小程序端的 socket.io.js,Github 上也有现成的库可以参考 wxapp-socket-io 示例代码如下:

// 小程序端示例代码
import io from 'vendor/wxapp-socket-io.js';
	
const socket = io('ws://127.0.0.1:7001');
socket.on('connect', function () {
  socket.emit('chat', 'hello world!');
});
socket.on('res', msg => {
  console.log('res from server: %s!', msg);
});

问题 & 建议

请访问 here.

MIT