4

I want to use socket.io in my Nuxtjs. Is it possible?

I tried this tutorial but I am getting the following error:

These dependencies were not found:

* fs in ./node_modules/socket.io/lib/index.js
* uws in ./node_modules/engine.io/lib/server.js
G'ofur N
  • 2,582
  • 3
  • 14
  • 21

3 Answers3

9

The better way to play with Nuxt.js + Socket.io is to follow this official example from core-team: https://github.com/nuxt/nuxt.js/tree/dev/examples/with-sockets

Nicolas Pennec
  • 7,533
  • 29
  • 43
  • 12
    Hi, I hope I'm not too late to the party but I decided to modularize that example, make it a bit more "npm-friendly" and push to the npm repo. I just authored [nuxt-socket-io](https://www.npmjs.com/package/nuxt-socket-io) The idea is: just npm install it, configure sockets in nuxt.config, and just use it. – RichS Oct 05 '19 at 03:29
  • Thanks for your input. @RichS – Herii Jul 28 '21 at 20:00
5

Updated answer with linked example on GitHub

I would suggest to use the nuxt-socket-io module. It is really easy to set up and has a nice documentation.

I built this litte demo example and I will list the steps that I took to build it (this is even a bit more thorough than the Setup section of the npm package):

  1. Add nuxt-socket-io dependency to your project:

    yarn add nuxt-socket-io # or npm install nuxt-socket-io

  2. (If you already have a socket.io server you can skip this part)

    Add following line to your nuxt.config.js file: serverMiddleware: [ "~/serverMiddleware/socket-io-server.js" ] (Please do not mix up serverMiddleware with middleware, this are two different things)

    Then, create the file ./serverMiddleware/socket-io-server.js where you can implement your socket.io server.

    // This file is executed once when the server is started
    
    // Setup a socket.io server on port 3001 that has CORS disabled
    // (do not set this to port 3000 as port 3000 is where
    // the nuxt dev server serves your nuxt application)
    const io = require("socket.io")(3001, {
      cors: {
        // No CORS at all
        origin: '*',
      }
    });
    
    var i = 0;
    // Broadcast "tick" event every second
    // Or do whatever you want with io ;)
    setInterval(() => {
      i++;
      io.emit("tick", i);
    }, 1000);
    
    // Since we are a serverMiddleware, we have to return a handler,
    // even if this it does nothing
    export default function (req, res, next) {
      next()
    }
    
  3. (If you already have Vuex set up, you can skip this)

    Add following empty Vuex store, i.e., create the file ./store/index.js, since the module needs Vuex set up.

    export const state = () => ({})
    
  4. Add nuxt-socket-io to the modules section of nuxt.config.js, this will enable socket-io client:

    {
      modules: [
        'nuxt-socket-io',
      ],
      // socket.io configuration
      io: {
      // we could have multiple sockets that we identify with names
      // one of these sockets may have set "default" to true
        sockets: [{
          default: true, // make this the default socket
          name: 'main', // give it a name that we can later use to choose this socket in the .vue file
          url: 'http://localhost:3001' // URL wherever your socket IO server runs
        }]
      },
    }
    
  5. Use it in your components:

    {
      data() {
        return {
          latestTickId: 0,
        };
      },
      mounted() {
        const vm = this;
    
        // use "main" socket defined in nuxt.config.js
        vm.socket = this.$nuxtSocket({
          name: "main" // select "main" socket from nuxt.config.js - we could also skip this because "main" is the default socket
        });
    
        vm.socket.on("tick", (tickId) => {
          vm.latestTickId = tickId;
        });
      },
    }
    
  6. Run it with npm run dev and enjoy your tick events :)

enter image description here

rafaelkendy
  • 69
  • 10
Markus Weninger
  • 11,931
  • 7
  • 64
  • 137
  • 1
    Hi @Markus I tried it but doesn't work, may I missed server.js ? please could you set all steps ? thanks – BKF Jan 18 '21 at 00:15
  • upvoted! could you kindly share what your server file looks like? – PirateApp Mar 18 '21 at 08:08
  • Hello @BKF. My original answer did not include any server code. I updated my answer to show the complete client *and* server side. – Markus Weninger Mar 27 '21 at 19:14
  • 1
    Hello @PirateApp. I did not have access to the code anymore, but I used my Saturday to set up the following demo project and updated the answer accordingly. Hope this helps! https://github.com/NeonMika/nuxt-socket-io-demo – Markus Weninger Mar 27 '21 at 19:15
3

Nuxt + socket.io

For me worked:

  1. Create project as nodejs app (not static page);
  2. Install socket.io npm i socket.io;
  3. Add serverMiddleware section to nuxt.config.js:
export default {
  ...,
  serverMiddleware: [
    {path: '/ws', handler: '~/api/srv.js'},
  ],
}
  1. Create middleware /app/srv.js:
const app = require('express')()
const socket = require('socket.io')
let server = null
let io = null

app.all('/init', (req, res) => {
  if (!server) {
    server = res.connection.server
    io = socket(server)

    io.on('connection', function (socket) {
      console.log('Made socket connection');

      socket.on('msg', msg => {
        console.log('Recived: ' + msg)

        setTimeout(() => {
          socket.emit('msg', `Response to: ${msg}`)
        }, 1000)
      })

      socket.on('disconnect', () => console.log('disconnected'))
    })
  }

  res.json({ msg: 'server is set' })
})

module.exports = app

Socket.io needs server which is not created in middleware, that's why is taken from firest request to app from res.connection.server.

  1. Create page pages/index.vue:
<template>
  <div class="container">
    <input v-model="msg">
    <button @click="socket.emit('msg', msg)">send</button>
    <br/>
    <textarea v-model="resps"></textarea>
  </div>
</template>

<script>
export default {
  head: {
    script: [
      {src: 'https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.0.4/socket.io.js'},
    ],
  },
  data () {
    return {
      socket: null,
      msg: 'wwJd',
      resps: '',
    }
  },
  mounted () {
    this.$axios.$get('/ws/init')
      .then(resp => {
        this.socket = io()
        this.socket.on('msg', msg => this.resps += `${msg}\n`)
      })
  },
}
</script>
  1. Run it npm run dev;
  2. Modify and enjoy :-)
NiKO
  • 2,610
  • 1
  • 19
  • 19