背景
我正在尝试使用Next.js建立和连接套接字。我遵循的是使用API调用来测试套接字服务器是否已经在运行的标准指南,如果没有,则创建一个。
我在pages/api/socket/io
上有一个API脚本,看起来像这样:
import { Server } from "socket.io";
export default function SocketHandler(req, res) {
if (res.socket.server.io) {
console.log("Already set up");
res.end();
return;
}
const io = new Server(res.socket.server);
// Event handler for client connections
io.on('connection', (socket) => {
const clientId = socket.id;
console.log('A client connected');
console.log(`A client connected. ID: ${clientId}`);
io.emit('client-new', clientId);
// Event handler for receiving messages from the client
socket.on('message', (data) => {
console.log('Received message:', data);
});
// Event handler for client disconnections
socket.on('disconnect', () => {
console.log('A client disconnected.');
});
});
res.socket.server.io = io;
res.end();
}
我在pages/chat.js
下有一个页面,它ping /api/socket/io
以确保套接字服务器正在运行,然后尝试连接到它。
import React, { useEffect, useState } from "react";
import io from "socket.io-client";
let socket;
const Page = () => {
const [message, setMessage] = useState("");
const [username, setUsername] = useState("");
useEffect(() => {
socketInitializer();
return () => {
socket.disconnect();
};
}, []);
async function socketInitializer() {
// ping the server to setup a socket if not already running
await fetch("/api/socket/io");
// Setup the Socket
socket = io({ path: "/api/socket/ping" });
// Standard socket management
socket.on('connect', () => {
console.log('Connected to the server');
});
socket.on('disconnect', () => {
console.log('Disconnected from the server');
});
socket.on('connect_error', (error) => {
console.log('Connection error:', error);
});
socket.on('reconnect', (attemptNumber) => {
console.log('Reconnected to the server. Attempt:', attemptNumber);
});
socket.on('reconnect_error', (error) => {
console.log('Reconnection error:', error);
});
socket.on('reconnect_failed', () => {
console.log('Failed to reconnect to the server');
});
// Manage socket message events
socket.on('client-new', (message) => {
console.log("new client", message);
});
socket.on('message', (message) => {
console.log("Message", message);
});
socket.on('client-count', (count) => {
console.log("clientCount", count)
});
}
function handleSubmit(e) {
e.preventDefault();
socket.emit("message", {
username,
message
});
setMessage("");
}
return (
<div>
<h1>Chat app</h1>
<h1>Enter a username</h1>
<input value={username} onChange={(e) => setUsername(e.target.value)} />
<div>
<form onSubmit={handleSubmit}>
<input
name="message"
placeholder="enter your message"
value={message}
onChange={(e) => setMessage(e.target.value)}
autoComplete={"off"}
/>
</form>
</div>
</div>
);
};
export default Page;
/api/socket/ping
是一个简单的脚本,除了返回ok状态之外,它没有做太多的事情。我假设它应该检查服务器是否正在运行,并保存任何逻辑以检查客户端在将来是否仍然有效,但它不应该阻止客户端在此时连接。
它看起来像这样:
export default async function handler(req, res) {
return res.status(200).send("OK");
}
问题
我遇到的问题是,似乎套接字服务器正在设置。但是,我无法让客户端连接。
我收到一个错误,提示我可能需要提供一些额外的配置选项作为客户端设置socket = io({ path: "/api/socket/ping" });
的一部分,但我不确定从哪里开始。
我在本地主机端口3000上运行服务器。这是我得到的错误:
Connection error: Error: server error
at Socket.onPacket (socket.js:318:1)
at Emitter.emit (index.mjs:136:1)
at Polling.onPacket (transport.js:97:1)
at callback (polling.js:115:1)
at Array.forEach (<anonymous>)
at Polling.onData (polling.js:118:22)
at Emitter.emit (index.mjs:136:1)
at Request.onLoad (polling.js:361:1)
at xhr.onreadystatechange (polling.js:297:1)
申请
请解释客户端无法连接的原因,并提出解决问题的建议。
2条答案
按热度按时间lx0bsm1f1#
8cdiaqws2#
@Louis的回答是正确的,将CORS确定为问题。我的解决方案有一点不同,我认为值得分享我的方法。
我在我的项目
yarn add cors
中添加了cors。然后修改我的io.js API端点,看起来像这样:io.js