Nuxt.jsでWebSocket、今回はsocket.ioを使う方法についての備忘録です。他によいアプローチがあるかもしれません。他の方の事例を参考にしながら、自分なりに整理してみました。
以下の3つのアプローチで記述してみます。
- moduleでserver.listenの上書き
- listenフック
- 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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
が呼ばれています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
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) }) }) }) } |
nuxt program
nuxtをプログラムから使用する方法です。これも、公式のサンプルに例があります。以下例では、公式サンプルを少し触っています。
参考)https://github.com/nuxt/nuxt.js/blob/dev/examples/with-sockets/server.js
server/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
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 |
サンプルプログラムは以下のとおり。
GitHub - moritetu/nuxt-with-socket.io: nuxt sample with socket.io
nuxt sample with socket.io. Contribute to moritetu/nuxt-with-socket.io development by creating an account on GitHub.
コメント