我知道可以通过反向代理(如Nginx、HAproxy等)传递请求,但我需要将请求重定向到相同域后缀中的另一个公共服务器。即从wss://example.com到wss://ws1.example.com。
下面是一个示例:

我需要重定向来自Nginx或Java的请求。组织起来是可能的吗?我是否需要在客户端处理重定向,或者这段代码就足够了?
var socket = new WebSocket("wss://example.com");
socket.onopen = function() {
alert("Connection established.");
};
socket.onclose = function(event) {
alert('Connection closed');
};
socket.onmessage = function(event) {
alert("Data: " + event.data);
};
socket.onerror = function(error) {
alert("Error " + error.message);
};发布于 2017-10-28 12:48:23
一旦发送了客户端的开放握手,客户端必须等待服务器的响应,然后才能发送任何进一步的数据。客户端必须验证服务器的响应,如下所示:
HTTP
所以,是否支持重定向完全取决于客户端,除非你在广泛的测试中发现所有相关的客户端都支持它(显然他们不支持),否则你显然不能依赖它。
您将不得不使用服务器端代理或客户端方案来手动将连接移动到另一台服务器。
发布于 2022-01-17 01:26:37
这个问题已经提了四年了,下面是你今天会怎么做:
在npm ws包中:
在套接字客户端构造函数(source)中将followRedirects设置为true。
在wscat实用程序中:
传递-L标志(source)。
在“大多数”浏览器中:
如果你不关心语义学,我对此进行wrote a package。否则,可以通过挂钩到WebSocket的构造函数来切换其构造函数中的URL,并最终支持重定向响应。
'use strict';
/* global window, WebSocket*/
(function (WebSocketNative = window.WebSocket) {
const debug = console.log;
debug('patching native WebSocket class to support HTTP redirects');
window.WebSocket = class {
constructor(url, ...args) {
this.work = [];
this.endpoint = url.replace(/^http/, 'ws');
debug('ws constructed with url: "%s" and endpoint: "%s"', url, this.endpoint);
return (
(async () => {
try {
const resolver =
window.WEBSOCKET_REDIRECT_RESOLVER || `${location.protocol}//${location.host}${location.pathname}`;
debug('websocket address resolver: "%s"', resolver);
const endpoint = `${resolver}?url=${encodeURIComponent(this.endpoint)}`;
debug('resolver query endpoint: "%s"', endpoint);
const response = await fetch(endpoint);
debug('resolver query response: "%o"', response);
const { dig, dug } = await response.json();
debug('resolver dig: "%o" dug: "%o"', dig, dug);
this.endpoint = dug;
} finally {
debug('websocket final endpoint: "%s"', this.endpoint);
this.socket = new WebSocketNative(this.endpoint, ...args);
debug('flushing %d queued operations', this.work.length);
for (const op of this.work) op(this.socket);
}
})(),
new Proxy(this, {
get: function (target, prop) {
debug('GETTER trace: "%s"', prop);
switch (prop) {
case 'construct':
case 'endpoint':
case 'socket':
case 'work':
debug('GETTER "%s" does not go through proxy', prop);
return Reflect.get(...arguments);
case 'OPEN':
case 'CLOSED':
case 'CLOSING':
case 'CONNECTING':
debug('GETTER "%s" is a static', prop);
return Reflect.get(WebSocketNative, prop);
case 'readyState':
case 'bufferedAmount':
return this.socket ? Reflect.get(this.socket, prop) : 0;
case 'binaryType':
return this.socket ? Reflect.get(this.socket, prop) : 'blob';
case 'extensions':
case 'protocol':
case 'url':
return this.socket ? Reflect.get(this.socket, prop) : '';
default:
return this.socket
? Reflect.get(this.socket, prop)
: function (...args) {
if (target.socket) {
debug('socket is ready, skip queueing get "%s" with args "%o"', prop, args);
return Reflect.get(target.socket, prop).call(target.socket, ...args);
} else {
debug('socket is not ready yet. queueing get "%s" with args "%o"', prop, args);
target.work.push((socket) => Reflect.get(socket, prop).call(socket, ...args));
}
};
}
},
set: function (target, prop, value) {
debug('SETTER trace: "%s"="%o"', prop, value);
switch (prop) {
case 'endpoint':
case 'socket':
case 'work':
return Reflect.set(...arguments);
default:
return this.socket
? Reflect.set(this.socket, prop, value)
: (() => {
if (target.socket) {
debug('socket is ready, skip queueing set "%s" with value "%o"', prop, value);
Reflect.set(socket, prop, value);
} else {
debug('socket is not ready yet, queueing set "%s" with value "%o"', prop, value);
target.work.push((socket) => Reflect.set(socket, prop, value));
}
return true;
})();
}
},
})
);
}
};
})(window.WebSocket);
这段代码覆盖了浏览器的原生WebSocket类,该类支持动态地将URL切换为ALTERNATE_WEBSOCKET_ADDRESS。您需要在某个地方定义ALTERNATE_WEBSOCKET_ADDRESS,因为不可能在浏览器环境中找出重定向响应的最终URL (无论是使用fetch还是XMLHttpRequest)。fetch仅用于检测重定向。您需要想出一种机制,以便在需要重定向时让ALTERNATE_WEBSOCKET_ADDRESS准备就绪。
https://stackoverflow.com/questions/46962881
复制相似问题