SocketIO 尝试使用与用于获取网页的浏览器相同的端口进行连接 [英] SocketIO tries to connect using same port as the browser used to get web page

查看:18
本文介绍了SocketIO 尝试使用与用于获取网页的浏览器相同的端口进行连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在本地提供内容,可通过 http://0.0.0.0:4000 访问.没问题,我得到了一个正确的网页,其中在脚本中包含以下行:

I am serving content locally, accessible through http://0.0.0.0:4000. That works ok, I get a correct webpage, which contains the following line inside a script:

var socket = io('http://example.com');

即我正在引用外部服务器.现在我的浏览器显示以下错误:

i.e. I am referencing an external server. Now my browser shows the followoing error:

GET http://example.com:4000/socket.io/?EIO=3&transport=polling&t=1417447089410-1 net::ERR_CONNECTION_REFUSED

也就是说,浏览器正在尝试使用与获取原始页面相同的端口进行连接.

That is, the browser is trying to connect using the same port that it used to get the original page.

当 SocketIO 服务器和 Web 服务器在同一个端口上侦听时,一切正常.

Everything works fine when both the SocketIO server and the web server listen on the same port.

我错过了什么吗?这是一个错误吗?有解决方法吗?谢谢.

Am I missing something? Is this a bug? Is there a workaround? Thank you.

推荐答案

可以在此处阅读,了解最初是如何设置普通 webSocket 的.这一切都始于一个有点标准的 HTTP GET 请求,但它设置了一些特殊的标头:

You can read here about how a plain webSocket is initially set up. It all starts with a somewhat standard HTTP GET request, but one that has some special headers set:

GET /chat HTTP/1.1
Host: example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

交换还可以允许主机仅强制执行来自某些来源的网页的请求.虽然可以从非网络浏览器代理欺骗此标头(因此服务器必须为此做好准备),但当 OP 使用真实浏览器时(假设没有代理修改它),它可能是正确的.

The interchange may also allow the host to enforce requests only from web pages on certain origins. While this header can be spoofed from non-web-browser agents (so the server has to be prepared for that), it will likely be correct when the OP is using a real browser (assuming no proxy is modifying it).

如果服务器接受传入的请求,它将返回一个类似于以下内容的 HTTP 响应:

If the server accepts the incoming request, it will then return an HTTP response that looks something like this:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

此时,曾经是 HTTP 套接字的套接字现在是 webSocket,并且两个端点都同意从现在开始使用 webSocket 数据格式.在此初始连接之后可能会进行某种形式的身份验证,也可以在连接的初始 HTTP 部分期间在身份验证中使用新的或现有的 cookie.

At this point, the socket which used to be an HTTP socket is now a webSocket and both endpoints have agreed that they're going to use the webSocket data format from now on. This initial connection may be followed by some form of authentication or new or existing cookies can also be used in the authentication during the initial HTTP portion of the connection.

socket.io 通过最初请求 /socket.io 的特定路径并向 URL 添加一些参数,在此基础上添加了一些增强功能.这允许 socket.io 协商是使用长轮询还是 webSocket,因此在初始化上述 webSocket 之前,客户端/服务器与 socket.io 之间有一些交换.

socket.io adds some enhancements on top of this by initially requesting a particular path of /socket.io and adding some parameters to the URL. This allows socket.io to negotiate whether it's going to use long polling or a webSocket so there are some exchanges between client/server with socket.io before the above webSocket is initialized.

那么,回到你的问题.socket.io 服务器只是监视普通 Web 端口上的所有传入 Web 请求(并查找它的特殊路径和特殊标头以指示 webSocket 启动而不是经典的 HTTP 请求).因此,它运行在与 Web 服务器相同的端口上.这样做的原因有很多,所有这些都为服务器和服务器基础设施提供了便利,因为他们不必配置他们的网络来接受除了他们已经接受的通常端口 80(或他们已经接受的任何端口)之外的任何东西用于网络请求).

So, back to your question. The socket.io server simply spies at all incoming web requests on the normal web port (and looks for both it's special path and for special headers to indicate a webSocket initiation rather than a classic HTTP request). So, it runs over the same port as the web server. This is done for a bunch of reasons, all of which provide convenience to the server and server infrastructure since they don't have to configure their network to accept anything other than the usual port 80 they were already accepting (or whatever port they were already using for web requests).

默认情况下,socket.io 中的域和端口将默认为与您所在网页相同的域和端口.因此,如果您没有在连接调用中指定一个或另一个,它将使用您所在网页的域或端口.如果您想同时使用不同的域和端口,则必须同时指定它们.

By default in socket.io, the domain and port will default to the same domain and port as the web page you are on. So, if you don't specify one or the other in your connect call, it will use the domain or port from the web page you are on. If you want to use both a different domain and port, then you must specify both of them.

这篇关于SocketIO 尝试使用与用于获取网页的浏览器相同的端口进行连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆