Socket.js连接报错:net::ERR_CONNECTION_REFUSED问题求助
解决Socket.io连接拒绝(ERR_CONNECTION_REFUSED)问题
首先咱们梳理下你的问题:你遇到了 GET http://localhost:3000/socket.io/?EIO=3&transport=polling&t=M3VEuNw net::ERR_CONNECTION_REFUSED 错误,服务器能打印socket message sending日志,但过段时间就触发连接拒绝。我看了你的前后端代码,发现了几个关键问题,逐个给你修正:
后端代码的核心问题
你的后端代码存在变量未定义、语法错误,以及Socket.io初始化和事件监听的逻辑错误:
1. socket.js:未正确监听客户端连接
你直接用socket.on,但这里的socket根本没被实例化——Socket.io需要先监听io的connection事件,才能拿到每个客户端的socket实例。
2. config.js:变量缺失+语法错误
- 没导入
http模块和socket.io的Server类; listen方法写在了类外面,不属于Config类的成员;this.socket = socket;里的socket完全没定义。
修正后的后端代码
socket.js
const messageService = require('./path-to-messageService'); // 替换成你的messageService实际路径 exports.connectSocket = (io) => { // 监听客户端连接,获取每个客户端的socket实例 io.on('connection', (socket) => { console.log('新客户端已连接'); // 监听客户端发来的send-message事件 socket.on('send-message', (message) => { messageService.sendMessage(message, (response) => { console.log('socket message sending', message); // 给指定接收者的房间发消息(需要客户端提前加入对应房间) io.to(message.receiverId).emit('recive-message', message); }); }); // 监听客户端断开连接 socket.on('disconnect', () => { console.log('客户端已断开连接'); }); }); }
config.js
import express from 'express'; import http from 'http'; // 导入http模块 import { Server } from 'socket.io'; // 导入Socket.io的Server类 import { connectSocket } from '../util/socket'; // 导入socket连接逻辑 class Config { constructor() { this.app = express(); this.http = http.createServer(this.app); // 创建HTTP服务器实例 // 初始化Socket.io,配置CORS解决跨域问题 this.io = new Server(this.http, { cors: { origin: "http://localhost:4200", // 替换成你的Angular项目端口 methods: ["GET", "POST"] } }); connectSocket(this.io); // 启动Socket.io的事件监听 } // 把listen方法移到类内部 listen(port) { this.http.listen(port, () => { console.log(`Server started: http://localhost:${port}/`); }); } } export default Config;
前端Angular代码的问题
你的SocketService存在事件调用逻辑错误,还有全局socket实例的问题:
1. 事件调用错误
socket.on(message.receiverId).emit('send-message', message);是完全错误的写法,socket.on是用来监听事件的,不是指定接收者;reciveMessages方法里用socket.emit('recive-message')错了,应该是监听这个事件,而不是发送它。
2. 全局socket实例
把socket实例放在服务外部会导致全局污染,应该在服务内部初始化。
修正后的SocketService代码
import { Injectable } from '@angular/core'; import { Message } from './interfaces/message'; import * as io from 'socket.io-client'; @Injectable() export class SocketService { private socket: SocketIOClient.Socket; constructor() { // 在服务内部初始化socket连接 this.socket = io.connect('http://localhost:3000/'); // 可选:监听连接状态,方便调试 this.socket.on('connect', () => { console.log('已连接到Socket服务器'); }); this.socket.on('disconnect', () => { console.log('与Socket服务器断开连接'); }); } // 发送消息到服务器 sendMessage(message: Message) { this.socket.emit('send-message', message); } // 监听服务器发来的消息,通过回调返回给组件 receiveMessages(callback: (message: Message) => void) { this.socket.on('recive-message', (message) => { console.log('收到消息:', message); callback(message); }); } }
额外关键注意点
- 房间机制:要实现给指定用户发消息,你需要让客户端在登录后调用
socket.join(userId)(比如在Angular的登录组件里调用this.socketService.socket.join(currentUser.id)),这样后端的io.to(message.receiverId).emit()才能精准发送到目标用户。 - 版本匹配:确保后端的
socket.io和前端的socket.io-client版本完全一致,版本不匹配经常会导致连接失败。 - 端口检查:确认后端确实运行在3000端口,Angular运行在你配置的端口(默认4200),并且没有防火墙或其他进程占用端口。
内容的提问来源于stack exchange,提问作者Swarnakshyari
相关产品推荐
相关产品推荐

