How to define socket variable globally

2019-06-17 08:25发布

问题:

I have this piece of code in my socketio file and here I can use socket simply.

import _ from 'lodash'
import mongoose from 'mongoose'

exports.register = (server, options, next) => {
  var io = require('socket.io')(server.listener)
  io.on('connection', async(socket) => {
    // here I can use socket.emit() and all
  })
  next()
}

exports.register.attributes = {
  name: 'socket'
}

Now, I need to use theio socket to emit events from various files and don't want to connect this io.on('connection', async(socket) => {}) every time.

How can I do this?

Thank you!!!

回答1:

next callback doesn't serve a good purpose here because it's synchronous. Since socket.io connection event can be triggered multiple times, it cannot be converted to a promise for easier chaining, so it's better for it to stay callback-based.

It can be:

var socketIo = require('socket.io')

exports.register = (server, options) => {
  var io = socketIo(server.listener);

  return onConnect => {
    io.on('connection', onConnect);
  };
}

So connection function is created once:

const myConnection = register(myServer);

And used through the application:

myConnection(client => {
  ...
});

This situation can also benefit from observables, e.g. RxJS.

In case the socket shouldn't support reconnections, this could be simplified to:

exports.register = (server, options) => {
  var io = socketIo(server.listener);

  return new Promise(resolve => {        
    io.once('connection', resolve);
  });
}

Connection promise is created once:

So connection function is created once:

const myConnection = register(myServer);

And used through the application:

const client = await myConnection;
...


回答2:

You can share functionality across your server instance with Server methods

import _ from 'lodash'
import mongoose from 'mongoose'

exports.register = (server, options, next) => {
  var io = require('socket.io')(server.listener)
  io.on('connection', async(socket) => {
    // here I can use socket.emit() and all
  })
  // here use server methods
  server.decorate('server', 'io', io);
  next()
}

exports.register.attributes = {
  name: 'socket'
}

Then in your controller

handler: function (request, reply) {
        const io = request.server.io;

    }