我在本地提供内容,可通过http://0.0.0.0:4000
访问。这工作正常,我得到一个正确的网页,其中包含脚本中的以下行:
var socket = io('http://example.com');
即。我正在引用外部服务器。现在我的浏览器显示了以下错误:
GET http://example.com:4000/socket.io/?EIO=3&transport=polling&t=1417447089410-1 net::ERR_CONNECTION_REFUSED
也就是说,浏览器尝试使用与获取原始页面相同的端口进行连接。
当SocketIO服务器和Web服务器都在同一端口上侦听时,一切正常。
我错过了什么吗?这是一个错误吗?有解决方法吗?谢谢。
答案 0 :(得分:1)
您can read here关于如何初始设置普通webSocket。这一切都以一个有点标准的HTTP GET请求开始,但是设置了一些特殊标头:
GET /chat HTTP/1.1
Host: example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13
交换还可以允许主机仅在某些来源的网页上强制执行请求。虽然这个标题可以从非Web浏览器代理中欺骗(因此服务器必须为此做好准备),但当OP使用真实的浏览器时(假设没有代理正在修改它),它可能是正确的。
如果服务器接受传入的请求,它将返回一个如下所示的HTTP响应:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
此时,曾经是HTTP套接字的套接字现在是一个webSocket,两个端点都同意他们从现在开始将使用webSocket数据格式。此初始连接之后可能会进行某种形式的身份验证,或者在连接的初始HTTP部分期间,也可以在身份验证中使用新的或现有的cookie。
socket.io
通过最初请求/socket.io
的特定路径并向URL添加一些参数,在此基础上添加了一些增强功能。这允许socket.io
协商它是否将使用长轮询或webSocket,因此在初始化上述webSocket之前,客户端/服务器与socket.io
之间存在一些交换。
所以,回到你的问题。 socket.io
服务器只是监视正常Web端口上的所有传入Web请求(并查找它的特殊路径和特殊标头以指示webSocket启动而不是经典HTTP请求)。因此,它运行在与Web服务器相同的端口上。这是出于多种原因而完成的,所有这些都为服务器和服务器基础设施提供了便利,因为他们不必将其网络配置为接受除了他们已经接受的通常端口80之外的任何其他端口(或者他们已经接受的任何端口)用于网络请求)。
默认情况下,socket.io
中的域和端口将默认为与您所在网页相同的域和端口。因此,如果您未在连接呼叫中指定其中一个,它将使用您所在网页中的域或端口。如果要同时使用不同的域和端口,则必须同时指定它们。