简体   繁体   中英

How to use socket globally in hapi js?

I am using hapijs in my MERN project and this is my socket.js file

import Emitter from '../config/emitter'

exports.register = (server, options, next) => {
  const io = require('socket.io')(server.listener)
  io.on('connection', (socket) => {
    // Subscribe this socket to `action` events
    socket.emit('action', action)
  })
  next()
}

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

I want to use this socket object globally anywhere in project(file) so that I can emit the event from there. How can I do that?

You could maybe have a variable with broader scope having a reference of the socket object and export it (simple); but the catch is it ll be undefined until it gets a proper value for it from io connection events:

import Emitter from '../config/emitter'

let Socket;

exports.register = (server, options, next) => {
  const io = require('socket.io')(server.listener)
  io.on('connection', (socket) => {
    // Subscribe this socket to `action` events
    if(typeof Socket==='undefined') Socket = socket;
    socket.emit('action', action);
  })
  next()
}

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

Example:

Server.js:

const Hapi = require("@hapi/hapi");

let myGlobalSocket;

const init = async () => {
  const server = Hapi.server({
    port: 3000,
    host: "localhost",
  });

  server.route({
    method: "GET",
    path: "/",
    handler: (request, h) => {
      return "Hello World!";
    },
  });
  await server.start();
  let io = require("socket.io")(server.listener);

  io.on("connection", function (socket) {
    myGlobalSocket = socket;
    console.log("connected");
    socket.on("ping", () => {
      socket.emit("pong");
    });

    // Do all the socket stuff here.
  });

  console.log("Server running on %s", server.info.uri);
};

process.on("unhandledRejection", (err) => {
  console.log(err);
  process.exit(1);
});

init();

// ... Tones Of Code !

const someOtherFuncInCode = () => {
  setInterval(() => {
    myGlobalSocket.emit("anyEmit");
  }, 1500);
};

someOtherFuncInCode();

Client.js

let ioc = require("socket.io-client");
let socket = ioc("ws://127.0.0.1:3000", {});

socket.on("connect", () => {
  console.log(`connect ${socket.id}`);
});

console.log("Loading Socket Client ");
socket.on("pong", function (msg) {
  console.log("YES I HAVE PONG");
});

socket.on("anyEmit", () => {
  console.log("I have anyEmit From Server !");
});

// setInterval(() => {
// // PingServer
//   socket.emit("ping");
// }, 2000);

I think You can use hapi-io for your needs. You can access your io or socket in your server or request variables.

npm install hapi-io --save

Register to plugins:

server.register({
  register: require('hapi-io'),
  options: {
    ...
  }
});

Access to io:

exports.register = function(server, options, next) {
 
  var io = server.plugins['hapi-io'].io;
  var socket = server.plugins['hapi-io'].socket;
 
};

Examples:

exports.register = function(server, options, next) {

  server.route({
    method: 'GET',
    path: '/users',
    config: {
      plugins: {
        'hapi-io': 'get-user'
      }
    },
    handler: function(request, reply) {
      var io = request.plugins['hapi-io'].io;
      var socket = request.plugins['hapi-io'].socket;

      reply({ success: true });

      if (socket) {
        // socket is only defined during a hapi-io/socket.io request
      }
    }
  });
};

Client:

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io();

  socket.emit('get-user', {}, function(res) {
    // res is the result from the hapi route
  });
</script>

For more info: https://www.npmjs.com/package/hapi-io , https://github.com/sibartlett/hapi-io (Examples in this link)

I think you can use global for accessing your socket anywhere in app

import Emitter from '../config/emitter'

exports.register = (server, options, next) => {
  const io = require('socket.io')(server.listener)
  global.io = io
  io.on('connection', (socket) => {
    // Subscribe this socket to `action` events
    socket.emit('action', action)
  })
  next()
}

// To use this anywhere, make sure your socket is initialized first

const io = global.io

You need to post more details with your question if you're not getting the answers you're looking for. Where is the server being initialized that you're passing into exports.register? Are you trying to plug the socket server into your initialized server or create another http server?

const Hapi = require('@hapi/hapi');
const socketio= require('socket.io');
const init = async () => {

    const server = Hapi.server({
        port: 3000,
        host: 'localhost'
    });

    await server.start();
    console.log('Server running on %s', server.info.uri);

  // require socket into our server
  const io = socketio(server);
  // include our secketio variable and require socket folder
  require('./socket')(io); // no socket has been initialized yet here. This is just plugged in to the right place. initialized in 'connection' action
};

init();

Without knowing more details this is all I can contribute, You would be able to pass the io variable to a function outside of your initializing function OR to another file which contains your io.on('connection', (socket).... logic. Once it is connected, you can start listening for events from the client side. In order for you to use it outside of the init() function though you will have to pass it to an outside function or another file and it can be received inside a module.exports= (io)=> {connection.....actions and emits... } and initialized there. Hopefully this helps. If not and you still need an answer I'd suggest showing more code snippets and including more details to help responses be more targeted to what you need. https://socket.io/docs/v3/server-initialization/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM