/egg-socket.io

egg plugin for socket.io

Primary LanguageJavaScriptMIT LicenseMIT

egg-socket.io

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

egg plugin for socket.io

Install

$ npm i egg-socket.io --save

Configuration

Change ${app_root}/config/plugin.js to enable Socket.IO plugin:

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

Configure Socket.IO in ${app_root}/config/config.default.js:

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

uws

If you want to replace the default us with uws, you can config like this:

exports.io = {
  init: { wsEngine: 'uws' },
};

read more about init config at: engine.io .

see config/config.default.js for more detail.

Deployment

Node Conf

Because of socket.io's design, the multi process socket.io server must work at sticky mode.

So, you must start server with sticky set to true, otherwise it will cause handshake exception.

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

Nginx Conf

if you use a nginx proxy server:

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 };
}

Usage

Directory Structure

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

Middleware

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

Connection Middleware

  • Write your connection middleware app/io/middleware/auth.js
module.exports = app => {
    return function* (next) {
        this.socket.emit('res', 'connected!');
        yield* next;
        // execute when disconnect.
        console.log('disconnection!');
    };
};
  • then config this middleware to make it works.

config/config.default.js

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

pay attention to the namespace, the config will only work for a specific namespace.

Packet Middleware

  • Write your packet middleware app/io/middleware/filter.js
module.exports = app => {
    return function* (next) {
        this.socket.emit('res', 'packet received!');
        console.log('packet:', this.packet);
        yield* next;
    };
};
  • then config this middleware to make it works.

config/config.default.js

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

pay attention to the namespace, the config will only work for a specific namespace.

Controller

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

example:

app/io/controller/chat.js

module.exports = app => {
  return function* () {
    const message = this.args[0];
    console.log(message);
    this.socket.emit('res', `Hi! I've got your message: ${message}`);
  };
};

next, config the router at app/router.js

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

Cluster

If your Socket.IO service is powered by mutil server, you must think about cluster solution.It can't work without cluster like broadcast ,rooms and so on.

It's very easy to implement sharing source and event dispatch with with socket.io-redis built in.

config at config/config.${env}.js

exports.io = {
  redis: {
    host: { redis server host },
    port: { redis server prot }
  }
};

Application will try to connect the redis server when booting.

Questions & Suggestions

Please open an issue here.

License

MIT