几秒钟后,Firefox 附加组件断开与 Kodi 的 WebSocket 连接
Firefox add-on drops WebSocket connection to Kodi after a few seconds
我决定为 Firefox 开发一个附加组件来控制 Kodi because I couldn't find any that already did everything I wanted. I have chosen to use WebSocket to communicate with Kodi so that I can receive events, but am having problems implementing the WebSocket portion of my add-on. Temporarily, I have created an add-on with a page-worker 仅用于测试 WebSocket 功能。我的开发插件和临时测试插件都表现出以下行为:
如果我直接在附加组件之外的 Firefox 中加载 test.html
(有关内容,请参阅 post 的底部),WebSocket 会按预期工作。当我播放或暂停 Kodi 时,连接保持打开状态并接收事件:
控制台输出 运行 test.html 在插件之外
Connection opened test.html:12:9
Object { jsonrpc: "2.0", method: "Player.OnPlay", params: Object } test.html:28:9
Object { jsonrpc: "2.0", method: "Player.OnPause", params: Object } test.html:28:9
Object { jsonrpc: "2.0", method: "Player.OnPlay", params: Object } test.html:28:9
Object { jsonrpc: "2.0", method: "Player.OnPause", params: Object } test.html:28:9
Object { jsonrpc: "2.0", method: "Player.OnPlay", params: Object } test.html:28:9
Object { jsonrpc: "2.0", method: "Player.OnPause", params: Object } test.html:28:9
Object { jsonrpc: "2.0", method: "GUI.OnScreensaverActivated", params: Object } test.html:28:9
但是,当 运行 从命令行使用 jpm run
加载项时,情况并非如此。连接在几秒后关闭(最多四秒)。 (请注意,在连接打开期间我可以很好地接收事件):
运行 使用 jpm
的插件的控制台输出
C:\Users\User\Desktop\example>jpm run
JPM [info] Starting jpm run on test
JPM [info] Creating a new profile
console.log: test: Connection opened
console.log: test: {"jsonrpc":"2.0","method":"Player.OnPlay","params":{"data":{"item":{"id":23,"type":"song"},"player":{"playerid":0,"speed":1}},"sender":"xbmc"}}
console.log: test: {"jsonrpc":"2.0","method":"Player.OnPause","params":{"data":{"item":{"id":23,"type":"song"},"player":{"playerid":0,"speed":0}},"sender":"xbmc"}}
console.log: test: Websocket error: undefined
console.log: test: Connection closed: 1006
我如何找出为什么连接在插件内部断开,但在插件外部却没有?我该如何补救这种奇怪的行为?
index.js:
var data = require("sdk/self").data;
var pageWorker = require("sdk/page-worker");
var pw = pageWorker.Page({
contentURL: data.url('test.html')
});
pw.port.on('message', function(message) {
console.log(message);
});
test.html:
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type=text/javascript>
var ws = new WebSocket('ws://192.168.2.34:9090/jsonrpc');
ws.onopen = function (event) {
try {
addon.port.emit('message', "Connection opened");
} catch (e) {
console.log("Connection opened");
}
};
ws.onerror = function (event) {
try {
addon.port.emit('message', "Websocket error: "+event.data);
} catch (e) {
console.log("Websocket error: "+event.data);
}
};
ws.onmessage = function (event) {
try {
addon.port.emit('message', JSON.parse(event.data));
} catch (e) {
console.log(JSON.parse(event.data));
}
};
ws.onclose = function (event) {
try {
addon.port.emit('message', "Connection closed: "+event.code);
} catch (e) {
console.log("Connection closed: "+event.code);
}
};
</script>
</head>
<body>
</body>
</html>
我安装了 Wireshark 并发现当 运行 在插件内部时发送了一个 Websocket ping 请求,但在插件外部没有。 Kodi 无法用 pong 响应 ping,因此 Firefox 关闭了连接。
有趣的是,加载项内的延迟连接和后续连接似乎没有生成 ping 请求,因此不会关闭。因此,解决方案是在连接关闭时简单地延迟或重新打开连接(无论如何这样做都可以处理网络连接丢失)。
test.html
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type=text/javascript>
//connect(); //generates a ping request
setTimeout(connect, 10000); //doesn't generate a ping request
function connect() {
this.ws = new WebSocket('ws://192.168.2.34:9090/jsonrpc');
this.ws.onopen = function (event) {
try {
addon.port.emit('message', "Connection opened");
} catch (e) {
console.log("Connection opened");
}
};
this.ws.onerror = function (event) {
try {
addon.port.emit('message', "Websocket error: "+event.data);
} catch (e) {
console.log("Websocket error: "+event.data);
}
};
this.ws.onmessage = function (event) {
try {
addon.port.emit('message', JSON.parse(event.data));
} catch (e) {
console.log(JSON.parse(event.data));
}
};
this.ws.onclose = function (event) {
try {
addon.port.emit('message', "Connection closed: "+event.code);
} catch (e) {
console.log("Connection closed: "+event.code);
}
setTimeout(connect, 5000); //re-opens connection, doesn't generate a ping request
};
}
</script>
</head>
<body>
</body>
</html>
我决定为 Firefox 开发一个附加组件来控制 Kodi because I couldn't find any that already did everything I wanted. I have chosen to use WebSocket to communicate with Kodi so that I can receive events, but am having problems implementing the WebSocket portion of my add-on. Temporarily, I have created an add-on with a page-worker 仅用于测试 WebSocket 功能。我的开发插件和临时测试插件都表现出以下行为:
如果我直接在附加组件之外的 Firefox 中加载 test.html
(有关内容,请参阅 post 的底部),WebSocket 会按预期工作。当我播放或暂停 Kodi 时,连接保持打开状态并接收事件:
控制台输出 运行 test.html 在插件之外
Connection opened test.html:12:9
Object { jsonrpc: "2.0", method: "Player.OnPlay", params: Object } test.html:28:9
Object { jsonrpc: "2.0", method: "Player.OnPause", params: Object } test.html:28:9
Object { jsonrpc: "2.0", method: "Player.OnPlay", params: Object } test.html:28:9
Object { jsonrpc: "2.0", method: "Player.OnPause", params: Object } test.html:28:9
Object { jsonrpc: "2.0", method: "Player.OnPlay", params: Object } test.html:28:9
Object { jsonrpc: "2.0", method: "Player.OnPause", params: Object } test.html:28:9
Object { jsonrpc: "2.0", method: "GUI.OnScreensaverActivated", params: Object } test.html:28:9
但是,当 运行 从命令行使用 jpm run
加载项时,情况并非如此。连接在几秒后关闭(最多四秒)。 (请注意,在连接打开期间我可以很好地接收事件):
运行 使用 jpm
的插件的控制台输出C:\Users\User\Desktop\example>jpm run
JPM [info] Starting jpm run on test
JPM [info] Creating a new profile
console.log: test: Connection opened
console.log: test: {"jsonrpc":"2.0","method":"Player.OnPlay","params":{"data":{"item":{"id":23,"type":"song"},"player":{"playerid":0,"speed":1}},"sender":"xbmc"}}
console.log: test: {"jsonrpc":"2.0","method":"Player.OnPause","params":{"data":{"item":{"id":23,"type":"song"},"player":{"playerid":0,"speed":0}},"sender":"xbmc"}}
console.log: test: Websocket error: undefined
console.log: test: Connection closed: 1006
我如何找出为什么连接在插件内部断开,但在插件外部却没有?我该如何补救这种奇怪的行为?
index.js:
var data = require("sdk/self").data;
var pageWorker = require("sdk/page-worker");
var pw = pageWorker.Page({
contentURL: data.url('test.html')
});
pw.port.on('message', function(message) {
console.log(message);
});
test.html:
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type=text/javascript>
var ws = new WebSocket('ws://192.168.2.34:9090/jsonrpc');
ws.onopen = function (event) {
try {
addon.port.emit('message', "Connection opened");
} catch (e) {
console.log("Connection opened");
}
};
ws.onerror = function (event) {
try {
addon.port.emit('message', "Websocket error: "+event.data);
} catch (e) {
console.log("Websocket error: "+event.data);
}
};
ws.onmessage = function (event) {
try {
addon.port.emit('message', JSON.parse(event.data));
} catch (e) {
console.log(JSON.parse(event.data));
}
};
ws.onclose = function (event) {
try {
addon.port.emit('message', "Connection closed: "+event.code);
} catch (e) {
console.log("Connection closed: "+event.code);
}
};
</script>
</head>
<body>
</body>
</html>
我安装了 Wireshark 并发现当 运行 在插件内部时发送了一个 Websocket ping 请求,但在插件外部没有。 Kodi 无法用 pong 响应 ping,因此 Firefox 关闭了连接。
有趣的是,加载项内的延迟连接和后续连接似乎没有生成 ping 请求,因此不会关闭。因此,解决方案是在连接关闭时简单地延迟或重新打开连接(无论如何这样做都可以处理网络连接丢失)。
test.html
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type=text/javascript>
//connect(); //generates a ping request
setTimeout(connect, 10000); //doesn't generate a ping request
function connect() {
this.ws = new WebSocket('ws://192.168.2.34:9090/jsonrpc');
this.ws.onopen = function (event) {
try {
addon.port.emit('message', "Connection opened");
} catch (e) {
console.log("Connection opened");
}
};
this.ws.onerror = function (event) {
try {
addon.port.emit('message', "Websocket error: "+event.data);
} catch (e) {
console.log("Websocket error: "+event.data);
}
};
this.ws.onmessage = function (event) {
try {
addon.port.emit('message', JSON.parse(event.data));
} catch (e) {
console.log(JSON.parse(event.data));
}
};
this.ws.onclose = function (event) {
try {
addon.port.emit('message', "Connection closed: "+event.code);
} catch (e) {
console.log("Connection closed: "+event.code);
}
setTimeout(connect, 5000); //re-opens connection, doesn't generate a ping request
};
}
</script>
</head>
<body>
</body>
</html>