Nuxt.jsでsocket.ioを使うやり方

NuxtJS

https:/nuxtjs.org/

Nuxt.jsでWebSocket、今回はsocket.ioを使う方法についての備忘録です。他によいアプローチがあるかもしれません。他の方の事例を参考にしながら、自分なりに整理してみました。

以下の3つのアプローチで記述してみます。

  1. moduleでserver.listenの上書き
  2. listenフック
  3. nuxt program

server.listenの上書き

これは、公式サンプルで書かれている内容です。

render:beforeフックの中で、listenメソッドを上書きしています。元々の処理では、protocolに応じたserverオブジェクトが作られlistenが呼ばれます。上記例では、プロトコルはhttpとしてserverオブジェクトを生成してsocket.ioライブラリに渡しています。

examples/with-sockets/io/index.js

引用)https://github.com/nuxt/nuxt.js/blob/dev/examples/with-sockets/io/index.js

import http from 'http'
import socketIO from 'socket.io'

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

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

    // Add socket.io events
    const messages = []
    io.on('connection', (socket) => {
      socket.on('last-messages', function (fn) {
        fn(messages.slice(-50))
      })
      socket.on('send-message', function (message) {
        messages.push(message)
        socket.broadcast.emit('new-message', message)
      })
    })
  })
}

listenフック

server.listenの以降で呼ばれるlistenフックを使います。serverは既にlistenが呼ばれています。

const socketIO = require('socket.io')

export default function () {
  this.nuxt.hook('listen', (server, listener) => {
    const io = socketIO(server)

    io.on('connection', (socket) => {
      socket.on('last-messages', function (fn) {
        fn(messages.slice(-50))
      })
      socket.on('send-message', function (message) {
        messages.push(message)
        socket.broadcast.emit('new-message', message)
      })
    })
  })
}

参考)https://stackoverflow.com/questions/63172001/where-do-i-add-this-websocket-code-in-the-new-nuxt-js-setup-since-it-does-not-ha

nuxt program

nuxtをプログラムから使用する方法です。これも、公式のサンプルに例があります。以下例では、公式サンプルを少し触っています。

参考)https://github.com/nuxt/nuxt.js/blob/dev/examples/with-sockets/server.js

server/index.js

const http = require('http')
const app = require('express')()
const { loadNuxt, build } = require('nuxt')

const isDev = process.env.NODE_ENV !== 'production'

app.get('/hello', (req, res) => {
  res.json({ message: 'hello' })
})

async function start() {
  const server = http.createServer(app)
  const socketIO = require('./io')
  const nuxt = await loadNuxt(isDev ? 'dev' : 'start')
  if (isDev) {
    build(nuxt)
  }

  app.use(nuxt.render)

  socketIO(server)

  const port = process.env.PORT || 3000
  const host = process.env.HOST || '0.0.0.0'
  server.listen(port, host)
  // eslint-disable-next-line no-console
  console.log('Server listening on localhost:' + port)
}

if (require.main === module) {
  start()
}

module.exports = app

server/io.js

const socketIO = require('socket.io')

const messages = []

function attachSocketIO(server) {
  const io = socketIO(server)

  io.on('connection', (socket) => {
    socket.on('last-messages', function (fn) {
      fn(messages.slice(-50))
    })
    socket.on('send-message', function (message) {
      messages.push(message)
      socket.broadcast.emit('new-message', message)
    })
  })

  return io
}

module.exports = attachSocketIO

サンプルプログラムは以下のとおり。

https://github.com/moritetu/nuxt-with-socket.io

参考リンク

byebyehaikikyou

日記やIT系関連のネタ、WordPressに関することなど様々な事柄を書き付けた雑記です。ITエンジニア経験があるのでプログラミングに関することなどが多いです。

シェアする

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください