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
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
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
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):
Add nuxt-socket-io dependency to your project:
yarn add nuxt-socket-io # or npm install nuxt-socket-io
(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()
}
(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 = () => ({})
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
}]
},
}
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;
});
},
}
Run it with npm run dev
and enjoy your tick events :)
For me worked:
npm i socket.io
;nuxt.config.js
:export default {
...,
serverMiddleware: [
{path: '/ws', handler: '~/api/srv.js'},
],
}
/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
.
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>
npm run dev
;