如何将Socket.io与Next.js API路由一起使用

时间:2019-08-15 15:45:05

标签: socket.io next.js

Next.js提供了serverless API routes。通过在./pages/api下创建文件,您可以运行服务,而我想使用此机制来获得Socket.io服务。

我已经创建了一个客户端:

./pages/client.js

import { useEffect } from 'react';
import io from 'socket.io-client';

export default () => {

  useEffect(() => {
    io('http://localhost:3000', { path: '/api/filename' });
  }, []);

  return <h1>Socket.io</h1>;
}

还有一个API路由:

./pages/api/filename.js

const io = require('socket.io')({ path: '/api/filename' });

io.onconnection = () => {
  console.log('onconnection');
}

io.on('connect', () => {
  console.log('connect');
})

io.on('connection', () => {
  console.log('connection');
})

export default (req, res) => {
  console.log('endpoint');
}

但是我无法让客户端连接到Socket.io服务器并成功看到以下任何内容:'onconnection''connect''connection'打印出来。

3 个答案:

答案 0 :(得分:11)

诀窍是将“ socket.io”仅插入到HTTP服务器一次,因此检查对api的每次访问。 尝试这样的事情:

./pages/api/socketio.js

import Server from 'socket.io'

const ioHandler = (req, res) => {
  if (!res.socket.server.io) {
    console.log('*First use, starting socket.io')

    const io = new Server(res.socket.server)

    io.on('connection', socket => {
      socket.broadcast.emit('a user connected')
      socket.on('hello', msg => {
        socket.emit('hello', 'world!')
      })
    })

    res.socket.server.io = io
  } else {
    console.log('socket.io already running')
  }
  res.end()
}

export const config = {
  api: {
    bodyParser: false
  }
}

export default ioHandler

./pages/socketio.jsx

import { useEffect } from 'react'
import io from 'socket.io-client'

export default () => {
  useEffect(() => {
    fetch('/api/socketio').finally(() => {
      const socket = io()

      socket.on('connect', () => {
        console.log('connect')
        socket.emit('hello')
      })

      socket.on('hello', data => {
        console.log('hello', data)
      })

      socket.on('a user connected', () => {
        console.log('a user connected')
      })

      socket.on('disconnect', () => {
        console.log('disconnect')
      })
    })
  })

  return <h1>Socket.io</h1>
}

答案 1 :(得分:1)

您必须具有/api/pusher/auth才能通过前端的推送程序进行身份验证。然后,您可以使用从中获得的密钥与Pusher通信。这是出于安全目的。您可以通过前端完成所有操作,但是根据您的应用程序,如果要保存数据(例如消息或聊天),则可能应该进行身份验证。

答案 2 :(得分:1)

您需要创建一个单独的 express 服务器,然后在 IO 对象上,您必须配置 cors 以及配置要在 app 变量上使用的 cors。我有我在这里制作的示例套接字服务器,作为适用于 NextJS 的答案。

const express = require("express");
const socket = require("socket.io");
const cors = require("cors");

const app = express();

app.use(cors());

const server = app.listen(process.env.PORT || 8080, () =>
  console.log("Port 8080")
);

// socket setup
const io = socket(server, {
  cors: {
     origin: "http://localhost:3000",
     methods: ["GET", "POST"],
     allowedHeaders: ["my-custom-header"],
    credentials: true
  }
});

io.on("connection", (socket) => {
  console.log("User connected");
  socket event example
   socket.on("chat", (data) => {
     console.log(data);
     io.sockets.emit("chat", data);
   });
});

你可以看到我用 app.use(cors())

const io = socket(server, {
  cors: {
    origin: "http://localhost:3000",
    methods: ["GET", "POST", "PATCH", "DELETE"],
    allowedHeaders: ["my-custom-header"],
    credentials: true
  } 
});

您可以在此处找到更多信息https://socket.io/docs/v3/handling-cors/