我在Chrome扩展程序中有一些Javascript,每3秒运行一次,并尝试建立与本地WebSocket服务器的连接。
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
$builder->add('Tasks', ChoiceType::class, array(
'choices' => array('task1','task2','task3));
我只期望在某些时间点运行本地WebSocket服务器。如果建立了连接,WebSocket服务器将发送一些javascript将立即使用的JSON数据。
当我进入开发人员工具时,我发现我在控制台中多次获得ERR_CONNECTION_REFUSED,因为在该端点显然没有任何东西,这是预期的行为。有没有办法抑制那些控制台输出或更好地处理这个问题?
编辑 - 更新了代码,我仍然将错误输出到控制台
setInterval(attemptConnection, 3000);
function attemptConnection() {
try {
var exampleSocket = new WebSocket("ws://localhost:8080");
exampleSocket.onmessage = function (event) {
var JsonObject = JSON.parse(event.data);
document.getElementById(JsonObject.elementTagValue).setAttribute("value", JsonObject.valueToSet);
}
}
catch(err) {
//do something here
}
答案 0 :(得分:0)
您不能使用try/catch
来捕获此错误,因为它是异步发生的。您应该使用onerror
事件处理程序。
function attemptConnection() {
var exampleSocket = new WebSocket("ws://localhost:8080");
exampleSocket.onmessage = function (event) {
var JsonObject = JSON.parse(event.data);
document.getElementById(JsonObject.elementTagValue).setAttribute("value", JsonObject.valueToSet);
};
exampleSocket.onerror = function() {
// do nothing
};
}
答案 1 :(得分:0)
假设你必须处理onerror
的错误,你也应该处理onclose
。
最简单的检查是错误代码1000
,这意味着正常的套接字关闭
exampleSocket.onclose = (event) => {
if (event.code != 1000) {
// "Normal closure, meaning that the purpose for which the connection was established has been fulfilled.";
}
}
虽然描述了here的错误代码的完整处理,但为了您的方便我放在这里:
exampleSocket.onclose = (event) => {
if (event.code == 1000)
reason = "Normal closure, meaning that the purpose for which the connection was established has been fulfilled.";
else if(event.code == 1001)
reason = "An endpoint is \"going away\", such as a server going down or a browser having navigated away from a page.";
else if(event.code == 1002)
reason = "An endpoint is terminating the connection due to a protocol error";
else if(event.code == 1003)
reason = "An endpoint is terminating the connection because it has received a type of data it cannot accept (e.g., an endpoint that understands only text data MAY send this if it receives a binary message).";
else if(event.code == 1004)
reason = "Reserved. The specific meaning might be defined in the future.";
else if(event.code == 1005)
reason = "No status code was actually present.";
else if(event.code == 1006)
reason = "The connection was closed abnormally, e.g., without sending or receiving a Close control frame";
else if(event.code == 1007)
reason = "An endpoint is terminating the connection because it has received data within a message that was not consistent with the type of the message (e.g., non-UTF-8 [http://tools.ietf.org/html/rfc3629] data within a text message).";
else if(event.code == 1008)
reason = "An endpoint is terminating the connection because it has received a message that \"violates its policy\". This reason is given either if there is no other sutible reason, or if there is a need to hide specific details about the policy.";
else if(event.code == 1009)
reason = "An endpoint is terminating the connection because it has received a message that is too big for it to process.";
else if(event.code == 1010) // Note that this status code is not used by the server, because it can fail the WebSocket handshake instead.
reason = "An endpoint (client) is terminating the connection because it has expected the server to negotiate one or more extension, but the server didn't return them in the response message of the WebSocket handshake. <br /> Specifically, the extensions that are needed are: " + event.reason;
else if(event.code == 1011)
reason = "A server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request.";
else if(event.code == 1015)
reason = "The connection was closed due to a failure to perform a TLS handshake (e.g., the server certificate can't be verified).";
else
reason = "Unknown reason";
}
var exampleSocket = new WebSocket("ws://localhost:8080");
exampleSocket.onmessage = function (event) {
var JsonObject = JSON.parse(event.data);
console.log(JsonObject)
exampleSocket.send(event.data);
exampleSocket.onerror = function () {
//do nothing
}
}
exampleSocket.onclose = (event) => {
if (event.code == 1000)
reason = "Normal closure, meaning that the purpose for which the connection was established has been fulfilled.";
else if(event.code == 1001)
reason = "An endpoint is \"going away\", such as a server going down or a browser having navigated away from a page.";
else if(event.code == 1002)
reason = "An endpoint is terminating the connection due to a protocol error";
else if(event.code == 1003)
reason = "An endpoint is terminating the connection because it has received a type of data it cannot accept (e.g., an endpoint that understands only text data MAY send this if it receives a binary message).";
else if(event.code == 1004)
reason = "Reserved. The specific meaning might be defined in the future.";
else if(event.code == 1005)
reason = "No status code was actually present.";
else if(event.code == 1006)
reason = "The connection was closed abnormally, e.g., without sending or receiving a Close control frame";
else if(event.code == 1007)
reason = "An endpoint is terminating the connection because it has received data within a message that was not consistent with the type of the message (e.g., non-UTF-8 [http://tools.ietf.org/html/rfc3629] data within a text message).";
else if(event.code == 1008)
reason = "An endpoint is terminating the connection because it has received a message that \"violates its policy\". This reason is given either if there is no other sutible reason, or if there is a need to hide specific details about the policy.";
else if(event.code == 1009)
reason = "An endpoint is terminating the connection because it has received a message that is too big for it to process.";
else if(event.code == 1010) // Note that this status code is not used by the server, because it can fail the WebSocket handshake instead.
reason = "An endpoint (client) is terminating the connection because it has expected the server to negotiate one or more extension, but the server didn't return them in the response message of the WebSocket handshake. <br /> Specifically, the extensions that are needed are: " + event.reason;
else if(event.code == 1011)
reason = "A server is terminating the connection because it encountered an unexpected condition that prevented it from fulfilling the request.";
else if(event.code == 1015)
reason = "The connection was closed due to a failure to perform a TLS handshake (e.g., the server certificate can't be verified).";
else
reason = "Unknown reason";
console.error(reason);
}
我在这里添加了一个完整的WebSocket客户端包装器,它通过一个简单的重新连接逻辑(从WebSocket节点官方示例移植)通过autoReconnectInterval
和maxAttempts
来处理重新连接。
function WebSocketClient() {
this.number = 0; // Message number
this.autoReconnectInterval = 5 * 1000; // ms
this.maxAttempts = 3;
this.attempts = 0;
}
WebSocketClient.prototype.open = function(url) {
var self = this;
this.url = url;
this.instance = new WebSocket(this.url);
this.instance.onopen = () => {
self.onopen();
}
this.instance.onmessage = (data, flags) => {
self.number++;
self.onmessage(data, flags, this.number);
}
this.instance.onclose = (e) => {
switch (e) {
case 1000: // CLOSE_NORMAL
console.log("WebSocket: closed normally");
break;
default: // Abnormal closure
if (self.attempts < self.maxAttempts) self.reconnect(e);
self.attempts++;
break;
}
this.onclose(e);
}
this.instance.onerror = (e) => {
switch (e.code) {
case 'ECONNREFUSED':
self.reconnect(e);
break;
default:
self.onerror(e);
break;
}
}
}
WebSocketClient.prototype.send = function(data, option) {
try {
this.instance.send(data, option);
} catch (e) {
this.instance.emit('error', e);
}
}
WebSocketClient.prototype.reconnect = function(e) {
var self = this;
console.log("WebSocketClient: retry in %s ms attempt %d", self.autoReconnectInterval, self.attempts);
setTimeout(function() {
console.log("WebSocketClient: reconnecting...");
self.open(self.url);
}, self.autoReconnectInterval);
}
WebSocketClient.prototype.onopen = function(e) {
console.log("WebSocketClient: open", arguments);
}
WebSocketClient.prototype.onmessage = function(data, flags, number) {
console.log("WebSocketClient: message", data);
}
WebSocketClient.prototype.onerror = function(e) {
console.log("WebSocketClient: error");
}
WebSocketClient.prototype.onclose = function(e) {
console.log("WebSocketClient: closed");
}
var wsc = new WebSocketClient();
wsc.open('wss://localhost:8080/');
wsc.onopen = function(e) {
console.log("WebSocketClient connected:", e);
this.send("echo");
}
wsc.onmessage = function(data, flags, number) {
console.log("WebSocketClient message", data);
}
答案 2 :(得分:0)
如果清除错误处理程序中的超时,则可能只能记录1错误。您还可以在onmessage函数中启动另一个Timeout,这样它只会在获取消息时运行。试一试
var timer = null;
function attemptConnection() {
var exampleSocket = new WebSocket("ws://localhost:8080");
exampleSocket.onmessage = function (event) {
timer = setTimeout(attemptConnection, 100);
var JsonObject = JSON.parse(event.data);
document.getElementById(JsonObject.elementTagValue).setAttribute("value", JsonObject.valueToSet);
exampleSocket.send(event.data);
}
exampleSocket.onerror = function (event) {
console.log('error')
//do nothin
clearTimeout(timer)
}
}
attemptConnection();