te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - How do I start websocket server (socketIO or otherwise) in Nuxt 3? Does not work the same as in Nuxt 2 - Stack Over
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I start websocket server (socketIO or otherwise) in Nuxt 3? Does not work the same as in Nuxt 2 - Stack Over

programmeradmin1浏览0评论

I am trying to convert my code from Nuxt 2 to Nuxt 3, and I have run into an issue with creating a websocket server in Nuxt 3.

It works perfectly fine in Nuxt 2 using this code:

// Nuxt 2: modules/socket.js
import http from 'http'
import socketIO from 'socket.io'

export default function () {
    this.nuxt.hook('render:before', () => {
        const server = http.createServer(this.nuxt.renderer.app)
        const io = socketIO(server)

        this.nuxt.server.listen = (port, host) => new Promise(resolve => server.listen(port || 3000, host || 'localhost', resolve))
        this.nuxt.hook('close', () => new Promise(server.close))

        io.on('connection', (socket) => {
            console.log("CONNECTED")
        })
    })
}
// Nuxt 2: plugins/socket.client.js
import io from 'socket.io-client'
const socket = io('http://localhost:3000')

export default ({}, inject) => {
    inject('socket', socket)
}
<!-- Nuxt 2: pages/index.vue -->
<template>
<div>
    <p>Check socket status in Vue devtools...</p>
</div>
</template>

<script>
export default {
    puted: {
        socket() {
            return this.$socket ? this.$socket : {};
        }
    }
}
</script>

However, in Nuxt 3 I cannot access this.nuxt.renderer.app in the modules/socket.js file (for http.createServer(...)), and I cannot figure out how to access the correct renderer.app elsewhere in a Nuxt3 module. My Nuxt 3 code looks like this:

// Nuxt 3: modules/socket.js
import http from 'http'
import socketIO from 'socket.io'

export default (_, nuxt) => {
    // Note that I use the 'ready' hook here - render:before is apparently not included in Nuxt3.
    nuxt.hook('ready', renderer => {
        // nuxt.renderer is undefined, so I've tried with renderer.app instead, with no luck.
        const server = http.createServer(renderer.app)
        const io = socketIO(server)

        nuxt.server.listen = (port, host) => new Promise(resolve => server.listen(port || 3000, host || 'localhost', resolve))
        nuxt.hook('close', () => new Promise(server.close))
            
        io.on('connection', () => {
            console.log("CONNECTION")
        })
    })
}
// Nuxt 3: plugins/socket.client.js
import io from 'socket.io-client'

export default defineNuxtPlugin(() => {
    const socket = io('http://localhost:3000')

    return {
        provide: {
            socket: socket
        }
    }
})
<!-- Nuxt 3: app.vue -->
<template>
  <div>
      <p>Check socket status in Vue devtools...</p>
  </div>
</template>

<script setup>
    const { $socket } = useNuxtApp()    
</script>

I would make a codesandbox link for you, but every time I try, it breaks before I even add any code. I think it does not correctly work with Nuxt3 yet. Has anyone successfully established a websocket server in a Nuxt 3 module yet? Or can anyone see what I am missing?

I am interested in any working solution, it does not necessarily have to be socket.io.

I am trying to convert my code from Nuxt 2 to Nuxt 3, and I have run into an issue with creating a websocket server in Nuxt 3.

It works perfectly fine in Nuxt 2 using this code:

// Nuxt 2: modules/socket.js
import http from 'http'
import socketIO from 'socket.io'

export default function () {
    this.nuxt.hook('render:before', () => {
        const server = http.createServer(this.nuxt.renderer.app)
        const io = socketIO(server)

        this.nuxt.server.listen = (port, host) => new Promise(resolve => server.listen(port || 3000, host || 'localhost', resolve))
        this.nuxt.hook('close', () => new Promise(server.close))

        io.on('connection', (socket) => {
            console.log("CONNECTED")
        })
    })
}
// Nuxt 2: plugins/socket.client.js
import io from 'socket.io-client'
const socket = io('http://localhost:3000')

export default ({}, inject) => {
    inject('socket', socket)
}
<!-- Nuxt 2: pages/index.vue -->
<template>
<div>
    <p>Check socket status in Vue devtools...</p>
</div>
</template>

<script>
export default {
    puted: {
        socket() {
            return this.$socket ? this.$socket : {};
        }
    }
}
</script>

However, in Nuxt 3 I cannot access this.nuxt.renderer.app in the modules/socket.js file (for http.createServer(...)), and I cannot figure out how to access the correct renderer.app elsewhere in a Nuxt3 module. My Nuxt 3 code looks like this:

// Nuxt 3: modules/socket.js
import http from 'http'
import socketIO from 'socket.io'

export default (_, nuxt) => {
    // Note that I use the 'ready' hook here - render:before is apparently not included in Nuxt3.
    nuxt.hook('ready', renderer => {
        // nuxt.renderer is undefined, so I've tried with renderer.app instead, with no luck.
        const server = http.createServer(renderer.app)
        const io = socketIO(server)

        nuxt.server.listen = (port, host) => new Promise(resolve => server.listen(port || 3000, host || 'localhost', resolve))
        nuxt.hook('close', () => new Promise(server.close))
            
        io.on('connection', () => {
            console.log("CONNECTION")
        })
    })
}
// Nuxt 3: plugins/socket.client.js
import io from 'socket.io-client'

export default defineNuxtPlugin(() => {
    const socket = io('http://localhost:3000')

    return {
        provide: {
            socket: socket
        }
    }
})
<!-- Nuxt 3: app.vue -->
<template>
  <div>
      <p>Check socket status in Vue devtools...</p>
  </div>
</template>

<script setup>
    const { $socket } = useNuxtApp()    
</script>

I would make a codesandbox link for you, but every time I try, it breaks before I even add any code. I think it does not correctly work with Nuxt3 yet. Has anyone successfully established a websocket server in a Nuxt 3 module yet? Or can anyone see what I am missing?

I am interested in any working solution, it does not necessarily have to be socket.io.

Share Improve this question edited Jun 7, 2022 at 16:18 ahbork asked Jun 7, 2022 at 16:16 ahborkahbork 1611 silver badge6 bronze badges 1
  • I tried to do essentially what you are trying to do in Java a few years ago - I couldn't get handshake to work (apparently you need Berkeley Sockets - developer.mozilla/en-US/docs/Web/API/WebSockets_API/…) the web socket server i am currently using is Ratchet, which I found to be fairly easy to set up and use (especially on Mac/unix) – ControlAltDel Commented Jun 7, 2022 at 16:29
Add a ment  | 

3 Answers 3

Reset to default 9

I figured it out!

Digging deep into the Nuxt 3 code, it turns out that they have a listen hook which provides the server parameter that I needed to set up the server. This information is really hard to find though.

I also managed to simplify the script a bit.

Here's the updated modules/socket.js:

import { Server } from 'socket.io'

export default (_, nuxt) => {
    nuxt.hook('listen', server => {
        const io = new Server(server)

        nuxt.hook('close', () => io.close())
        
        io.on('connection', () => {
            console.log("CONNECTION")
        })
    })
}

Everything else can remain the same

Based on @ahbork's response and a addition from the Nuxt 3 docs, I got this on Vue 3 + Nuxt 3 + Typescript:

import { Server } from 'socket.io'
import { defineNuxtModule } from '@nuxt/kit'

export default defineNuxtModule({
  setup(options, nuxt) {
    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', `wele ${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`)
        })
      })
    })
  },
})

thx anbork I'm use ws it the same method create file in /modules/wsServer.ts

import { WebSocketServer } from "ws";
import { defineNuxtModule } from "@nuxt/kit";

export default defineNuxtModule({
  setup(options, nuxt) {
    nuxt.hook("listen", (server) => {
      const wss = new WebSocketServer({ server });
      nuxt.hook("close", () => wss.close());
      wss.on("connection", (ws) => {
        console.log("connection");
        ws.on("message", (data) => console.log("received: %s", data));
        ws.send("someting");
      });
    });
  },
});

and in page file

let ws;
onMounted(() => {
  const wsProtocol = window.location.protocol === "https:" ? "wss:" : "ws:";
  ws = new WebSocket(`${wsProtocol}//${window.location.host}`);
  ws.onopen = () => console.log("connected");
  ws.onmessage = ({ data }: any) => {
    console.log("data", data);
  };
});
const sendMessage = () => {
  ws.send("hello");
};

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论