Firefox插件会在几秒钟后将WebSocket连接丢弃到Kodi

时间:2016-04-05 05:37:36

标签: javascript firefox websocket firefox-addon kodi

我决定开发一个Firefox附加组件来控制Kodi,因为我找不到任何已经完成我想要的东西。我已经选择使用WebSocket与Kodi进行通信,以便我可以接收事件,但是在实现我的附加组件的WebSocket部分时遇到了问题。暂时,我创建了一个带有page-worker的加载项,仅用于测试WebSocket功能。我的开发加载项和临时测试加载项都表现出以下行为:

如果我在加载项之外的Firefox中直接加载test.html(请参阅帖子的内容),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>

1 个答案:

答案 0 :(得分:0)

我安装了Wireshark并发现在加载项内部运行时发送了Websocket ping请求,但不是在加载项之外。 Kodi没有用乒乓球响应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>