将两个 socket.io 客户端连接在一起(建立套接字到套接字,跨浏览器连接)

Connect two socket.io clients together (Establish a socket to socket, cross browser connection)

本文关键字:连接 套接字 建立 浏览器 在一起 客户端 两个 socket io      更新时间:2023-09-26

我想知道是否有任何方法可以使用 socket.io 客户端在两个浏览器之间建立P2P连接(但我愿意使用任何其他可能解决问题的方法(。

这两个浏览器目前都连接到一个节点.js应用程序,该应用程序使用 Express 提供 HTTP 请求,该应用程序存储两个客户端的 IP 地址(以及本地运行时的端口(。我想做的是添加第三个连接,直接链接两个客户端(我们称它们为 A 和 B(,以便消息/数据将直接从一个客户端传输到另一个客户端,而无需通过节点.js服务器传输。

这可行吗?如果是这样,如何?

到目前为止,我已经尝试使用以下代码连接两个客户端(我们称它们为 A 和 B(:

客户 A:

A_to_server_socket = io();
A_to_server_socket.on('p2p', function(address_B){
    A_to_B_socket = io(address_B); // Instantiates a new socket
    A_to_B_socket.on('connect', function() {
            console.log('Connected!');
    });  
});

我不确定客户端 B 的代码。但是我已经尝试过:

  1. 对 B 重复上述代码,使用 B 自己的地址(以覆盖连接到服务器的默认值(

  2. 对 B 重复上面的代码,这次使用 A 的地址

  3. B_to_server_socket侦听新的连接事件

然而,无论 B 的代码如何,当运行 A 的代码时,我在 Firefox 上遇到"跨源请求被阻止"错误,或者在 Chrome 上遇到"无法加载资源:net::ERR_CONNECTION_REFUSED",然后是"net::ERR_CONNECTION_REFUSED"。

任何关于解决方案的提示,或更好地了解问题和套接字如何工作的见解,都将非常受欢迎。

我将尝试将我的评论总结为答案。

在 TCP 中,当一个端点 A 连接到另一个端点 B 时,将建立连接。 要连接到终结点 B,该主机必须"侦听"来自其他主机的传入连接。 在典型的 Web 请求中,浏览器与 Web 服务器建立 TCP 连接,这是有效的,因为 Web 服务器正在侦听特定端口上的传入请求,当其中一个请求传入时,它会接受传入请求以建立活动的 TCP 连接。 因此,您必须让一端发起请求,另一端侦听请求。

出于各种安全原因,浏览器本身不会"侦听"传入的连接,因此您无法直接连接到它们。 它们只允许您出站连接到互联网上的其他侦听代理。 因此,如果浏览器从不侦听传入的 webSocket 连接,则无法建立真正的对等(例如浏览器到浏览器(webSocket 连接。

此外,TCP的设计使得你不能让两个浏览器都连接到一个公共服务器,然后以某种方式让该服务器连接它们的管道,这样两个浏览器现在只是直接相互连接。 TCP就是不是那样工作的。 中间的代理可以通过与每个客户端的单独连接将数据包从一个客户端转发到另一个客户端(这就是聊天应用程序通常的工作方式(,但中间的代理不能简单地将两个TCP连接插入在一起,以便数据包直接从一个客户端发送到另一个客户端(并且不再通过服务器(,就像消防员连接两个消防水带一样。 TCP就是不是那样工作的。 可能会有一些复杂的方案,涉及将数据包标头重写为从端点 A 发送的数据包转发到端点 B,看起来它来自服务器,但这仍然涉及服务器作为中间人或代理。

解决此问题的常用方法是让每个浏览器连接到公共服务器,并让服务器充当中间人或流量警察,将数据包从一个浏览器转发到另一个浏览器。

现有的 P2P 应用程序(浏览器之外(的工作原理是让每个客户端实际侦听传入连接(充当服务器(,以便另一个客户端可以直接连接到它们。 P2P本身比这更复杂,因为需要有一种方法来发现要连接的IP地址(因为客户端通常不在DNS中(,并且通常存在防火墙,需要两端之间进行一些合作才能使防火墙允许传入连接。 但是,唉,这种侦听传入连接的能力不是纯JavaScript的浏览器允许你做的事情。

没有类似"使用 socket.io 客户端的两个浏览器之间的连接"之类的东西。

但是有"两个浏览器都连接到一个节点.js应用程序使用Express提供HTTP请求,该应用程序跟踪两个客户端的IP地址(以及本地运行时的端口(。

如果您想在两个浏览器之间建立 P2P 连接,以下可能是一种方法。

  1. 当您获得客户端 A 连接时,加入房间"P2P">
  2. 当您获得客户端 B 连接时,加入房间"P2P">
  3. 要在客户端 A 和客户端 B 之间进行交换,请使用

    socket.broadcast.to('P2P'(.emit("message", "Good Morning"(;

希望这可能会有所帮助。