是否可以使用同一个端口启用 tcp、http 和 websocket?
Posted
技术标签:
【中文标题】是否可以使用同一个端口启用 tcp、http 和 websocket?【英文标题】:Is it possible to enable tcp, http and websocket all using the same port? 【发布时间】:2012-11-27 06:46:03 【问题描述】:我正在尝试在同一端口上启用tcp、http 和websocket.io 通信。我从 tcp 服务器(//// 行上方的部分)开始,它起作用了。然后我运行了echo server example found on websocket.io(在 //// 行下方),它也起作用了。但是当我尝试将它们合并在一起时,tcp 不再起作用。
那么,是否可以使用同一个端口启用 tcp、http 和 websockets?还是我必须在另一个端口上监听 tcp 连接?
var net = require('net');
var http = require('http');
var wsio = require('websocket.io');
var conn = [];
var server = net.createServer(function(client) //'connection' listener
var info =
remote : client.remoteAddress + ':' + client.remotePort
;
var i = conn.push(info) - 1;
console.log('[conn] ' + conn[i].remote);
client.on('end', function()
console.log('[disc] ' + conn[i].remote);
);
client.on('data', function(msg)
console.log('[data] ' + conn[i].remote + ' ' + msg.toString());
);
client.write('hello\r\n');
);
server.listen(8080);
///////////////////////////////////////////////////////////
var hs = http.createServer(function(req, res)
res.writeHead(200,
'Content-Type' : 'text/html'
);
res.end(['<script>', "var ws = new WebSocket('ws://127.0.0.1:8080');", 'ws.onmessage = function (data) ws.send(data); ;', '</script>'].join(''));
);
hs.listen(server);
var ws = wsio.attach(hs);
var i = 0, last;
ws.on('connection', function(client)
var id = ++i, last
console.log('Client %d connected', id);
function ping()
client.send('ping!');
if (last)
console.log('Latency for client %d: %d ', id, Date.now() - last);
last = Date.now();
;
ping();
client.on('message', ping);
);
【问题讨论】:
HTTP 通常运行在 TCP 之上。 HTTP 和 TCP 是什么意思? 这就是我怀疑的原因。我的服务器需要通过浏览器与 websockets 通信,并通过移动应用程序与 TCP 连接通信。因此我需要这两种协议。 也许您可以作为原始 TCP 进行侦听,如果检测到 HTTP,则手动转发到其他处理程序。同样,如果您从 HTTP 服务器检测到 WS(WS 以 HTTP 开头),请再次委托。 通常你应该使用 HTTP 并通过 URL 进行区分,或者在不同的端口上运行原始 TCP。 请注意,HTTP 流通常使用 GZIP 可以很好地压缩,并且使用原始套接字不会获得太多收益(使用一个双工 TCP 连接而不是两个单工连接并不是真正的胜利)。你确实得到了消息序列化(除非 WS 也是双工的)。 【参考方案1】:同一端口可以处理多个不同的协议,但有一些注意事项:
服务器必须有某种方式来检测(或协商)客户端希望使用的协议。您可以将单独的端口视为检测客户端希望使用的协议的常规方式。
只有一个服务器进程可以实际监听该端口。此服务器可能仅用于检测协议类型,然后转发到多个其他服务器,但每个端口由单个服务器进程拥有。
您不能支持服务器首先发言的多个协议(因为无法检测客户端的协议)。您可以支持单个服务器优先协议和多个客户端优先协议(通过在接受后添加一个短暂的延迟以查看客户端是否会发送数据),但这有点不稳定。
WebSocket 协议的一个明确设计目标是允许 WebSocket 和 HTTP 协议共享相同的服务器端口。初始 WebSocket 握手是一个 HTTP 兼容的升级请求。
websockify 服务器/网桥是可以在同一端口上使用 5 种不同协议的服务器示例:HTTP、HTTPS(加密 HTTP)、WS(WebSockets)、WSS(加密 WebSockets)和 Flash 策略响应.服务器查看传入请求的第一个字符以确定它是 TLS 加密的(HTTPS 或 WSS)还是以“
免责声明:我制作了 websockify
【讨论】:
@kanaka:一个端口可以连接多少个客户端?我想知道一个 Java Web 应用程序一次可以处理多少个 Web 套接字连接?对于来自客户端的每个 Web 套接字请求,我们是否需要服务器上的差异端口? @DaxJoshi 作为一个单独的问题可能会更好。它也真的不需要对 Websockets 做任何事情。 TCP连接被接受的服务器端口可以处理大量的连接。您没有为每个客户端使用单独的服务器端口。在 websockify 案例中,如果您希望不同的客户端通过 websockify 连接到不同的目标,那么您应该查看 websockify 的TokenFile plugin/target config 功能。【参考方案2】:简短回答 - 不,您不能在同一端口上运行不同的 TCP/HTTP/Websocket 服务器。
冗长的答案 - websockets 和 HTTP 都在 TCP 之上工作。因此,您可以将 http 服务器或 websocket 服务器视为自定义 TCP 服务器(具有一些状态管理和协议特定的编码/解码)。一台机器上不可能有多个套接字绑定到同一个端口/协议对,所以第一个会获胜,后面的会得到套接字绑定异常。
【讨论】:
不,您不能将多个“服务器”或服务绑定到同一个端口,但您当然可以拥有一个可以同时处理 HTTP 和 Websocket 请求的服务。以上是关于是否可以使用同一个端口启用 tcp、http 和 websocket?的主要内容,如果未能解决你的问题,请参考以下文章
CDN,是不是UDP端口也可以加速,如果UDP加速用怎样搞?
为啥 HTTP/HTTPS 代理和 Socks 代理可以在一个端口上工作?