Reputation: 238
I am creating a socket.io implementation in a Nuxt 3 app. The websockets work when I am in development mode but I get this error error message. I am using Nuxt version nuxt v3.0.0-rc.8, here is what my nuxt.config.ts file looks like:
import { defineNuxtConfig } from 'nuxt';
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
css: [
'primevue/resources/themes/saga-blue/theme.css',
'primevue/resources/primevue.css',
'primeicons/primeicons.css'
],
build: {
transpile: [
'primevue'
],
},
modules: [
'./modules/socket'
]
})
Here is what my modules/sockets.ts file looks like:
import { Server } from 'socket.io';
import { defineNuxtModule } from '@nuxt/kit';
export default defineNuxtModule({
setup(_, nuxt) {
console.log('Socket Read');
nuxt.hook('listen', (server) => {
console.log('Socket listen', server.address(), server.eventNames())
const io = new Server(server)
nuxt.hook('close', () => io.close())
io.on('connection', (socket) => {
console.log('Connection', socket.id)
})
io.on('connect', (socket) => {
socket.emit('message', `welcome ${socket.id}`)
socket.broadcast.emit('message', `${socket.id} joined`)
socket.on('message', function message(data: any) {
console.log('message received: %s', data)
socket.emit('message', { data })
})
socket.on('disconnecting', () => {
console.log('disconnected', socket.id)
socket.broadcast.emit('message', `${socket.id} left`)
})
})
});
},
});
Here is what my plugins/socket.client.ts file looks like
import io from 'socket.io-client';
export default defineNuxtPlugin(() => {
const socket = io('http://localhost:3000');
return {
provide: {
io: socket
}
}
});
Here is my app.vue file that has simple button implementation of a socket emit event
<template>
<button @click="sendMessage" class="btn btn-primary">Send Message</button>
</template>
<script setup lang="ts">
const { $io } = useNuxtApp();
const sendMessage = () => {
console.log('Click');
$io.emit("message", "new message sent");
};
</script>
Here is my package.json file
{
"private": true,
"scripts": {
"build": "nuxi build",
"dev": "nuxi dev",
"generate": "nuxi generate",
"preview": "nuxi preview",
"start": "node .output/server/index.mjs"
},
"devDependencies": {
"nuxt": "^3.0.0-rc.8"
},
"dependencies": {
"primeflex": "^3.2.1",
"primeicons": "^5.0.0",
"primevue": "^3.16.1",
"socket.io": "^4.5.2",
"socket.io-client": "^4.5.2"
}
}
Here is a replit playground that I set up
Upvotes: 4
Views: 6309
Reputation: 238
I found a solution to the problem, for some reason Nuxt 3 wasn't executing my socket.io module on startup in production. I created my own solution using serverHandlers (previously serverMiddleware) and here is what I made.
Here is my nuxt.config.ts file
import { defineNuxtConfig } from 'nuxt';
// https://v3.nuxtjs.org/api/configuration/nuxt.config
export default defineNuxtConfig({
css: [
'primevue/resources/themes/saga-blue/theme.css',
'primevue/resources/primevue.css',
'primeicons/primeicons.css'
],
build: {
transpile: [
'primevue'
],
},
serverHandlers: [
{
route: '/ws',
handler: '~/server-middleware/socket'
}
]
})
Here is my server-middleware/socket.ts
import { Server } from 'socket.io';
const io = new Server(3001, {
cors: {
origin: '*',
}
});
io.on('connection', (socket) => {
console.log('Connection', socket.id)
})
io.on('connect', (socket) => {
socket.emit('message', `welcome ${socket.id}`)
socket.broadcast.emit('message', `${socket.id} joined`)
socket.on('message', function message(data: any) {
console.log('message received: %s', data)
socket.emit('message', { data })
})
socket.on('disconnecting', () => {
console.log('disconnected', socket.id)
socket.broadcast.emit('message', `${socket.id} left`)
})
});
export default function (req, res, next) {
res.statusCode = 200
res.end()
}
Here is my plugins/socket.client.ts
import { io } from 'socket.io-client';
//Socket Client
const socket = io('http://localhost:3001');
export default defineNuxtPlugin(() => {
return {
provide: {
io: socket
}
}
});
Here is my app.vue
<template>
<button @click="sendMessage" class="btn btn-primary">Send Message</button>
</template>
<script setup lang="ts">
const { $io } = useNuxtApp();
const sendMessage = () => {
console.log('Click');
$io.emit("message", "new message sent");
};
</script>
And here is my package.json
{
"private": true,
"scripts": {
"build": "nuxi build",
"dev": "nuxi dev",
"generate": "nuxi generate",
"preview": "nuxi preview",
"start": "node .output/server/index.mjs"
},
"devDependencies": {
"nuxt": "^3.0.0-rc.8"
},
"dependencies": {
"primeflex": "^3.2.1",
"primeicons": "^5.0.0",
"primevue": "^3.16.1",
"socket.io": "^4.5.2",
"socket.io-client": "^4.5.2"
}
}
Upvotes: 10