どどんてぃ のリファクタリングにあたりフレームワークをNuxtに変えようと思ってタイトルのあれこれを調べてみたらなんか全然うまく行かなかったので、素朴に socket.ioの公式ドキュメントを見ながら実装したらあっさりうまくいきましたってお話。公式ドキュメント大事。
初期設定
npx create-nuxt-app projectName
からプロジェクト作るわけですが、
- サーバーサイドのフレームワークはExpressにしておく
- レンダリングの方法はユニバーサルレンダリングにしておく
がやりやすいかと。あとはお好きに。無事プロジェクトフォルダが完成したら
cd projectName
npm install --save socket.io
npm install --save socket.io-client
と socket.io 関連のライブラリをインストール
サーバーサイド
適当に動作確認ができればいいので改変は最小限。
server/index.js
const express = require('express')
const consola = require('consola')
const { Nuxt, Builder } = require('nuxt')
const app = express()
// socket.io の require
const socket = require('socket.io')
// Import and Set Nuxt.js options
const config = require('../nuxt.config.js')
config.dev = process.env.NODE_ENV !== 'production'
async function start () {
// Init Nuxt.js
const nuxt = new Nuxt(config)
const { host, port } = nuxt.options.server
await nuxt.ready()
// Build only in dev mode
if (config.dev) {
const builder = new Builder(nuxt)
await builder.build()
}
// Give nuxt middleware to express
app.use(nuxt.render)
// Listen the server
// サーバ情報を保存しておく
const server = app.listen(port, host)
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true
})
// ソケットの作成
const io = socket(server)
// 接続された時の処理
io.on('connection', (socket) => {
// 適当にイベントを送り返してみる
socket.emit('news', { msg: 'hello!' })
// イベントを受信した時の処理定義
socket.on('ev', (msg) => {
console.log('ev', msg)
})
})
}
start()
クライアントサイド
pages/index.vue
<template>
<div class="container">
<div>
<logo />
<h1 class="title">
projectName
</h1>
<h2 class="subtitle">
description
</h2>
<div class="links">
<a
href="https://nuxtjs.org/"
target="_blank"
class="button--green"
>
Documentation
</a>
<a
href="https://github.com/nuxt/nuxt.js"
target="_blank"
class="button--grey"
>
GitHub
</a>
<!-- イベント送信のためのボタンを追加 -->
<a
class="button--grey"
@click="sendEve"
>
sendEv
</a>
</div>
</div>
</div>
</template>
<script>
// クライアントライブラリのインポート
import io from 'socket.io-client'
import Logo from '~/components/Logo.vue'
export default {
components: {
Logo
},
data () {
return {
socket: io()
}
},
// マウントされた時に初期化をする
mounted () {
this.socket.on('news', (data) => {
console.log(data)
})
},
methods: {
sendEve () {
this.socket.emit('ev', 'hogehoge')
}
}
}
</script>
<style>
(略)
</style>
これでサーバサイドとクライアントサイドのコンソールを見ながら、イベントの送受信が確認できればオッケー。