Integrating Socket.io with Next.js 14 /api Routes

2.5k views Asked by At

I'm currently working on a project using Next.js 14 and I'm facing challenges integrating Socket.io with the /api routes. I've explored various resources but haven't found a clear and concise guide on how to set up Socket.io specifically with the latest version of Next.js.

I would greatly appreciate it if someone could provide a step-by-step guide or share their experiences on successfully implementing Socket.io in conjunction with Next.js 14 /api routes. Additionally, any code snippets or examples demonstrating the integration would be incredibly helpful.

Thank you in advance for your assistance!

I tried the old methods of doing it but nothing worked. Some time it is a error of 500 internal server error sometime it is 405 and 404. I also got these errors in the terminal...

⨯ Detected default export in 'F:\Projects\NextJs\chat_u\chat_u\app\api\socket\route.js'. Export a named export for 
each HTTP method instead.
 ⨯ No HTTP methods exported in 'F:\Projects\NextJs\chat_u\chat_u\app\api\socket\route.js'. Export a named export for each HTTP method.
3

There are 3 answers

1
Lohit On

I think it's better have a seperate server running for that because next.js is a servless framework.

3
Arthur Trembley On

Here are my code lines.

/api/socket.ts

import type { Server as HTTPServer } from "http"
import type { Socket as NetSocket } from "net"
import type { NextApiRequest, NextApiResponse } from "next"
import type { Server as IOServer } from "socket.io"
import { Server } from "socket.io"

interface SocketServer extends HTTPServer {
  io?: IOServer | undefined
}

interface SocketWithIO extends NetSocket {
  server: SocketServer
}

interface NextApiResponseWithSocket extends NextApiResponse {
  socket: SocketWithIO
}

export async function GET(_req: NextApiRequest, res: NextApiResponseWithSocket) {
  if (res.socket?.server?.io) {
    res.status(200).json({ success: true, message: "Socket is already running", socket: `:${PORT}` })
    return
  }

  console.log("Starting Socket.IO server on port:", PORT)

  const io = new Server({ path: "/api/socket", addTrailingSlash: false, cors: { origin: "*" } }).listen(PORT)

  io.on("connect", socket => {
    const _socket = socket
    console.log("socket connect", socket.id)
    _socket.broadcast.emit("welcome", `Welcome ${_socket.id}`)
    socket.on("disconnect", async () => {
      console.log("socket disconnect")
    })
  })

  res.socket.server.io = io
  res.status(201).json({ success: true, message: "Socket is started", socket: `:${4000}` })
}

// client code

import { Socket, io } from "socket.io-client"

export const Test= () => {
  const data: any = {}
  const socket = io(`:PORT`, { path: "/api/socket", addTrailingSlash: false })
  socket.on("connect", () => {
    console.log("Connected")
  })
  socket.on("disconnect", () => {
    console.log("Disconnected")
  })
  socket.on("connect_error", async err => {
    console.log(`connect_error due to ${err.message}`)
    await fetch("/api/socket")
  })
}

Hope it will be helpful for you.

0
sol On

i am encountering the same problem as you. the more i research the issue the more i have to come to the conclusion that next.js is just fundamentally incompatible with a classic client server architecture. they are trying to solve usecases specific to most standard websites. but when you want the high interactivity between client and server that is usually accomplished by using a websocket, you just encounter fundamental design differences. it looks like next.js doesnt want there to be one central server that accepts and holds websocket connections. and the more they develop further the more strikt they force the users to adopt this model. i am looking for alternative react frameworks that allow a more classic client server model. if you find any alternatives i would love to learn about them