Nuxt.jsでWebSocketを利用したリアルタイム通信

Nuxt.jsでWebSocketを利用したリアルタイム通信

はじめに

今回をNuxt.jsを利用したフロントエンドにWebSocketを導入してみた内容を共有させていただきます。

Nuxt.jsとは

Nuxt.jsVue.jsなどをベースにしたJavascriptフレームワークの一種です。
Nuxt.jsにはVue.jsの機能に加えて、サーバーサイドレンダリング、Vue RouterによるルーティングやVuexによる状態管理など、すぐに開発着手できる開発環境と拡張性と提供しています。
(※Vue.js入門 基礎から実践アプリケーション開発までより一部引用)

WebSocketとは

WebSocketとはユーザーのブラウザーとサーバー間で対話的な通信セッションを開くことができる先進技術です。この API によって、サーバーにメッセージを送信したり、応答をサーバーにポーリングすることなく、イベント駆動型のレスポンスを受信したりすることができます。
(※MDN Web Docsより引用)

手順

前提

本サンプルでは、Node.jsバージョンは16.13.2を使用しています。

$ node -v
v16.13.2

またJavascriptパッケージマネージャーとしてyarnを使用しています。

セットアップ

まずは雛形となるNuxt.jsアプリケーションをcreate-nuxt-appを使用してセットアップします。

$ yarn create nuxt-app nuxt-websocket-sample

サーバーサイド側

サーバーサイド側でWebSocketを実現するために、今回はwsライブラリを使用します。

$ yarn add ws

以下のようにサーバーサイド側の実装を行います。
server-middleware/ws.js

const WebSocket = require('ws')

const wss = new WebSocket.Server({ port: 8080 })

// 接続処理
wss.on('connection', (ws) => {
  // クライアントからのリクエストを受け取った際の処理
  ws.on('message', (message) => {
    // 送信元を含むすべてのWebSocket接続済みクライアントに送信
    wss.clients.forEach((client) => {
      client.send(message)
    })
  })
})

module.exports = { handler: wss }

今回はnuxt.jsの機構に則ってserverMiddlewareとしてサーバーを追加します。
nuxt.config.jsに先ほど作成したws.jsファイルを指定します。

export default {
  // 追加
  serverMiddleware: [
    { path: '/', handler: '~/server-middleware/ws.js' }
  ]
}

クライアント側

送信ボタンを押下すると、メッセージが表示される簡易なチャット機能を作成します。
クライアント側はJavascriptネイティブなWebSocket APIを利用しています。
なお、UIフレームワークとしてVuetifyを利用しています。

pages/chat.vue

<template>
  <div>
    <v-text-field
      v-model="text"
      label="text here"
    />
    <v-btn
      color="success"
      @click="onSend"
    >
      Send
    </v-btn>
    <v-list>
      <v-list-item v-for="(message, i) in messages" :key="i">
        {{ message }}
      </v-list-item>
    </v-list>
  </div>
</template>

<script>
export default {
  name: 'ChatPage',
  data () {
    return {
      text: '',
      messages: [],
      // WebSocket接続
      socket: new WebSocket('ws://localhost:8080')
    }
  },
  mounted () {
    // WebSocket接続が確立された時に実行される
    this.socket.onopen = () => console.log('socket connected')
    // メッセージ受信時の処理
    this.socket.onmessage = (event) => {
      if (!event.data) { return }
      const message = event.data
      this.messages.push(message)
    }
  },
  methods: {
    onSend () {
      if (!this.text) {
        return
      }
      // サーバー側にメッセージを送信
      this.socket.send(this.text)
      this.text = ''
    }
  }
}
</script>

動作確認

以下のコマンドを実行するとローカル端末上でアプリケーションが起動します。

$ yarn dev

同じ画面を2つ開いた状態で、片方の画面から送信を行うと両方の画面上でメッセージが更新されていることが確認できました。

開発者ツール上でもWebSocketでデータ通信できていることが確認できました。

参考

Handling Websockets with Express
Svelte + WebSocketでシンプルなチャットアプリを作る
Nuxt.jsでWebSocketを使ってみる #nuxtjs #vuejs
【Node.js】WebSocketことはじめ【Javascript】