Next.jsだけでsocket.io通信したい
·
wamo
やりたいこと
クライアント側でつぶやいた内容が、別のクライアントで即座に反映される。
socket.ioのインストール
npm i socket.io socket.io-client
レスポンスの型定義を作成
src/pages/types/socket.d.ts
に作成します。
import { Server as NetServer, Socket } from "net"
import { NextApiResponse } from "next"
import { Server as SocketIOServer } from "socket.io"
export type NextApiResponseServerIO = NextApiResponse & {
socket: Socket & {
server: NetServer & {
io: ServerIO
}
}
}
socket.io サーバー用のAPIを作成
src/pages/api/socket.ts
に作成します。(これはapi内ならどこでもいい)
import { NextApiRequest, NextApiResponse } from 'next'
import { Server as NetServer, Socket } from "net"
import { Server as ServerIO } from "socket.io"
import { NextApiResponseServerIO } from "types/socket"
export default async function handler(req: NextApiRequest, res: NextApiResponseServerIO) {
if (!res.socket.server.io) {
console.log(`New Socket.io server...`)
const httpServer: NetServer = res.socket.server as any
const io = new ServerIO(httpServer, {
path: `/api/socket`,
})
res.socket.server.io = io
}
res.end();
}
socket.io の更新用APIを作成
要はデータの更新(作成)をするときのAPIです。
src/pages/api/post.ts
に作成します(これもapi内ならどこでもいい)
import type { NextApiRequest, NextApiResponse } from 'next'
import { PrismaClient } from '@prisma/client'
import { NextApiResponseServerIO } from "types/socket"
const prisma = new PrismaClient()
export default async function handler(
req: NextApiRequest,
res: NextApiResponseServerIO
) {
const { method } = req
switch (method) {
case 'POST':
const post = await prisma.post.create({
data: req.body,
})
res.socket.server.io.emit("message", req.body)
res.status(200).json(post)
break
}
}
socket.io-clientを作成
import { useEffect } from "react";
import { io } from 'socket.io-client'
useEffect(() => {
const socket = io("http://localhost:3000", {
path: '/api/socket',
})
socket.on('connect', () => {
console.log("SOCKET CONNECTED!", socket.id)
})
socket.on(`message`, (message: string) => {
console.log(message)
})
if (socket) return () => socket.disconnect()
}, [])
return (
...
)
あとはnext dev
してメッセージを送信するとちゃんとメッセージを受信するはずです。