NodeJS 为什么我的Socketio服务器不能与Angular一起工作

ckocjqey  于 2023-06-05  发布在  Node.js
关注(0)|答案(1)|浏览(303)

我尝试在Express服务器中实现套接字,代码如下所示:应用程序类:

app: Application;
server: http.Server | https.Server;
sockets: SocketIo;

constructor() {
   this.app = express();
   this.app.use(cors());
   this.server = http.createServer(this.app);
   this.iniciarSockets();
   this.server.listen(3000, () => .....)
}

private async iniciarSockets() {
 this.sockets = new SocketIo(this.server);
}

我的SocketIo类看起来像这样:

import http from 'http';
import https from 'https';
import { Server, Socket } from 'socket.io';
export class SocketIo {
  io: Server;

  constructor(server: http.Server | https.Server) {
      this.io = require("socket.io")(server);

       this.io.on("connection", (socket: Socket) => {
          console.log("New connection");
          socket.emit("test event", "Here is some data");
        
      })
}
}

但是当我尝试使用服务从Angular访问它时,我在控制台中得到以下三个错误:404 socket.io/?EIO=4&transport=polling&t=OXzMsOL Not Found(Not Found)404 Not Found(Not Found)
访问XMLHttpRequest在'http://localhost:3000/socket.io/?EIO=4&transport=polling&t=OXzMsOR' from origin ' http://localhost:4200 ' has been blocked by CORS policy:请求的资源上不存在“Access-Control-Allow-Origin”标头。
GET http://localhost:3000/socket.io/?EIO=4&transport=polling&t=OXzMsOR net::ERR_FAILED 200(OK)
我的Angular服务看起来像这样,我在Youtube上看了一段视频:

export class WebSocketService {

  socket: any;
  readonly url: string = "ws://localhost:3000";

  constructor() {
    this.socket = io(this.url);
   }

  listen(eventName: string) {
    return new Observable((subscriber) => {
      this.socket.on(eventName, (data) => {
        subscriber.next(data);
      })
    })
  }

  emit(eventName: string, data: any) {
    this.socket.emit(eventName, data);
  }
}
xghobddn

xghobddn1#

您在尝试从端口4200服务的网页访问端口3000时似乎遇到了COR权限问题。这是angular使用的两个服务器模型(每个服务器在不同的端口上)的典型问题。
此错误消息似乎是关键:

Access to XMLHttpRequest at 'http://localhost:3000/socket.io/?EIO=4&transport=polling&t=OXzMsOR' 
from origin 'http://localhost:4200' 
has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource.

你有几个选择。如果您的socket.io客户端指定传输为WebSocket,则socket.io将不会使用一系列普通http请求启动连接过程,因此不会受到COR限制。
您可以通过更改以下客户端代码来实现此目的:

this.socket = io(this.url);

对此:

this.socket = io(this.url, { transports: ['websocket'] });

这将告诉socket.io直接转到WebSocket传输,因此不受COR限制。
或者,您可以将适当的代码添加到您的www.example.com服务器所挂接的Web服务器socket.io,以允许COR请求。
仅供参考,我总是在www.example.com中使用http: URLsocket.io,而不是ws:,所以我也建议你改变这一点:

readonly url: string = "ws://localhost:3000";

对此:

readonly url: string = "http://localhost:3000";

也许ws URL可以工作(我实际上不知道),但它实际上是一个http请求,它建立了初始的socket.io传输,所以这似乎是您应该使用的。

相关问题