NuxtJs 可以使用 Socket.io 吗?

Is it possible to use Socket.io with NuxtJs?

我想在我的 Nuxtjs 中使用 socket.io。可能吗?

我试过 this tutorial 但出现以下错误:

These dependencies were not found:

* fs in ./node_modules/socket.io/lib/index.js
* uws in ./node_modules/engine.io/lib/server.js

使用 Nuxt.js + Socket.io 的更好方法是遵循核心团队的官方示例:https://github.com/nuxt/nuxt.js/tree/dev/examples/with-sockets

Nuxt + socket.io

为我工作:

  1. 将项目创建为 nodejs 应用程序(不是静态页面);
  2. 安装socket.ionpm i socket.io;
  3. 将 serverMiddleware 部分添加到 nuxt.config.js:
export default {
  ...,
  serverMiddleware: [
    {path: '/ws', handler: '~/api/srv.js'},
  ],
}
  1. 创建中间件/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 需要未在中间件中创建的服务器,这就是为什么从 res.connection.server.

对应用程序的第一次请求中获取的原因
  1. 创建页面 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. 运行这npm run dev;
  2. 修改并享受:-)

在 GitHub

上更新了带有链接示例的答案

我建议使用 nuxt-socket-io module. It is really easy to set up and has a nice documentation.

我构建了 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 的 npm 包):

  1. 将 nuxt-socket-io 依赖项添加到您的项目中:

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

  2. (如果你已经有一个socket.io服务器你可以跳过这部分)

    将以下行添加到您的 nuxt.config.js 文件中:serverMiddleware: [ "~/serverMiddleware/socket-io-server.js" ](请不要混淆 serverMiddleware 和 middleware,这是两个不同的东西)

    然后,创建文件 ./serverMiddleware/socket-io-server.js,您可以在其中实现 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. (如果你已经设置好Vuex,可以跳过)

    添加以下空 Vuex 存储,即创建文件 ./store/index.js,因为该模块需要设置 Vuex。

    export const state = () => ({})
    
  4. 将 nuxt-socket-io 添加到 nuxt.config.js 的模块部分,这将启用 socket-io 客户端:

    {
      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. 在您的组件中使用它:

    {
      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. 运行 它与 npm run dev 并享受你的报价事件:)