从节点模块到 chrome 扩展的 WebSocket 连接在 Windows 10 中自动关闭
WebSocket connection from node module to chrome extension closing automatically in Windows 10
我使用 https://www.npmjs.com/package/ws npm 包在我的 npm 模块和我的 chrome 扩展之间进行通信。
连接正在打开,但将在几秒钟后关闭。
我研究了这个主题,我发现我应该在 webSocket 服务器和客户端之间来回发送消息以保持它的活动。
我每 2 秒处理一次此消息,但我的连接仍在关闭。
有趣的是,关闭事件仅在节点模块端触发,而 chrome 插件不会触发该事件。这是来自我的 chrome 扩展的代码:
function myPlugin() {
myPlugin.prototype.socket = false;
myPlugin.prototype.isConnected = false;
myPlugin.prototype.port = false;
myPlugin.prototype.pluginName = "Tab Reloader";
myPlugin.prototype.init();
};
myPlugin.prototype = {
initListeners: function () {
chrome.browserAction.onClicked.addListener(function(tab) {
if (!this.isConnected) {
this.connectToServer();
} else {
this.disconnectFromServer();
}
}.bind(this));
},
setPort: function () {
chrome.storage.sync.get(['port'], function(items) {
this.port = items.port || '8001';
}.bind(this));
},
getTabsToReload: function (callback) {
var tabsToReload = [];
chrome.storage.sync.get(['hostName'], function(items) {
if (!items.hostName) {
chrome.tabs.query({active: true}, function(tabs) {
tabs.forEach(function (tab) {
tabsToReload.push(tab);
});
callback(tabsToReload);
});
} else {
chrome.tabs.query({}, function(tabs) {
tabs.forEach(function (tab) {
if (tab.url.indexOf(items.hostName) != -1) {
tabsToReload.push(tab);
}
});
callback(tabsToReload);
});
}
}.bind(this));
},
initSocketListeners: function () {
var fileExtIndex,
fileExt,
file;
this.socket.onmessage = function (ev) {
file = ev.data.toString();
fileExtIndex = file.lastIndexOf('.') + 1;
fileExt = file.slice(fileExtIndex),
fileNameStandardize = file.replace(/\/g, '\/'),
indexOfLastSeparator = fileNameStandardize.lastIndexOf('/') + 1,
fileName = file.slice(indexOfLastSeparator);
if (file != 'pong' && file.indexOf('connected to server!!!') == -1) {
//do stuff
} else {
if (file == 'pong') {
this.isAlive = true;
}
}
}.bind(this);
this.socket.addEventListener('close', function (ev) {
console.log('connection Closed')
clearInterval(this.aliveInterval);
chrome.browserAction.setIcon({
path: {
"16": "img/icon_disabled_16.png",
"24": "img/icon_disabled_24.png",
"32": "img/icon_disabled_32.png"
}
});
this.isConnected = false;
}.bind(this));
},
connectToServer: function () {
this.socket = new WebSocket("ws://localhost:" + this.port);
this.socket.addEventListener('error', function (ev) {
this.isConnected = false;
alert('Error connecting to websocket server, make sure it\'s running and port ' + this.port + ' is not occupied by other process');
}.bind(this));
this.socket.addEventListener('open', function (ev) {
this.isConnected = true;
this.socket.send(this.pluginName + ' connected to server!!!');
this.initSocketListeners();
this.stayConnected();
this.isAlive = true;
this.aliveInterval = setInterval(function () {
this.checkIfAlive();
}.bind(this), 2500);
this.getTabsToReload(function (tabsToReload) {
tabsToReload.forEach(function (tab) {
chrome.tabs.update(tab.id, {url: tab.url});
});
});
chrome.browserAction.setIcon({
path: {
"16": "img/icon_active_16.png",
"24": "img/icon_active_24.png",
"32": "img/icon_active_32.png"
}
});
}.bind(this));
},
disconnectFromServer: function () {
this.socket.close();
},
stayConnected: function () {
setTimeout(function () {
this.socket.send('ping');
if (this.isConnected) {
this.stayConnected();
}
}.bind(this), 1000);
},
checkIfAlive: function () {
this.isAlive = false;
setTimeout(function () {
console.log(this.isAlive)
if (!this.isAlive) {
console.log(this.isAlive)
this.disconnectFromServer();
}
}.bind(this), 2000);
},
init: function () {
this.setPort();
this.initListeners();
}
}
window.onload = new myPlugin();
这是我的节点模块代码:
"use strict";
//var WebSocketServer = require('websocketserver');
//var WebSocketServer = require("nodejs-websocket")
var WebSocket = require('ws');
class MyModule {
constructor(options) {
this.options = options;
this.server = false;
this.pluginName = 'Some';
this.isConnected = false;
this.connection = false;
this.init();
return this.refreshTab.bind(this);
}
init() {
var port = this.options ? this.options.port : false;
this.server = new WebSocket.Server({port: port || 8001});
this.server.on('connection', (websocket) => {
console.log('Connection open');
this.websocket = websocket;
this.isConnected= true;
this.initListeners();
});
}
refreshTab(uploadedFiles) {
if (this.isConnected) {
if (Array.isArray(uploadedFiles)) {
uploadedFiles.forEach(function (el) {
this.websocket.send(el.toString());
}.bind(this));
} else {
this.websocket.send(uploadedFiles ? uploadedFiles.toString() : 'reload');
}
} else {
console.log('You are not connected to server yet.');
}
}
initListeners() {
this.websocket.on('message', (message) => {
if (message == 'ping') {
this.websocket.send('pong');
}
});
this.websocket.on('close', () => {
this.isConnected = false;
console.log(this.pluginName + ' connection is closed');
});
}
};
module.exports = MyModule;
感谢任何帮助,
提前致谢。
所以我的问题实际上是 manifest.json
"background": {
"scripts": ["js/tab_reloader.js"],
"persistent": false
}
"persistent" 设置为 false,它将我的背景页面转换为事件页面。并且事件页面在一段时间后从内存中卸载,这正在终止连接。在我将 "persistent" 设置为 true 后问题得到解决。
我使用 https://www.npmjs.com/package/ws npm 包在我的 npm 模块和我的 chrome 扩展之间进行通信。
连接正在打开,但将在几秒钟后关闭。
我研究了这个主题,我发现我应该在 webSocket 服务器和客户端之间来回发送消息以保持它的活动。
我每 2 秒处理一次此消息,但我的连接仍在关闭。
有趣的是,关闭事件仅在节点模块端触发,而 chrome 插件不会触发该事件。这是来自我的 chrome 扩展的代码:
function myPlugin() {
myPlugin.prototype.socket = false;
myPlugin.prototype.isConnected = false;
myPlugin.prototype.port = false;
myPlugin.prototype.pluginName = "Tab Reloader";
myPlugin.prototype.init();
};
myPlugin.prototype = {
initListeners: function () {
chrome.browserAction.onClicked.addListener(function(tab) {
if (!this.isConnected) {
this.connectToServer();
} else {
this.disconnectFromServer();
}
}.bind(this));
},
setPort: function () {
chrome.storage.sync.get(['port'], function(items) {
this.port = items.port || '8001';
}.bind(this));
},
getTabsToReload: function (callback) {
var tabsToReload = [];
chrome.storage.sync.get(['hostName'], function(items) {
if (!items.hostName) {
chrome.tabs.query({active: true}, function(tabs) {
tabs.forEach(function (tab) {
tabsToReload.push(tab);
});
callback(tabsToReload);
});
} else {
chrome.tabs.query({}, function(tabs) {
tabs.forEach(function (tab) {
if (tab.url.indexOf(items.hostName) != -1) {
tabsToReload.push(tab);
}
});
callback(tabsToReload);
});
}
}.bind(this));
},
initSocketListeners: function () {
var fileExtIndex,
fileExt,
file;
this.socket.onmessage = function (ev) {
file = ev.data.toString();
fileExtIndex = file.lastIndexOf('.') + 1;
fileExt = file.slice(fileExtIndex),
fileNameStandardize = file.replace(/\/g, '\/'),
indexOfLastSeparator = fileNameStandardize.lastIndexOf('/') + 1,
fileName = file.slice(indexOfLastSeparator);
if (file != 'pong' && file.indexOf('connected to server!!!') == -1) {
//do stuff
} else {
if (file == 'pong') {
this.isAlive = true;
}
}
}.bind(this);
this.socket.addEventListener('close', function (ev) {
console.log('connection Closed')
clearInterval(this.aliveInterval);
chrome.browserAction.setIcon({
path: {
"16": "img/icon_disabled_16.png",
"24": "img/icon_disabled_24.png",
"32": "img/icon_disabled_32.png"
}
});
this.isConnected = false;
}.bind(this));
},
connectToServer: function () {
this.socket = new WebSocket("ws://localhost:" + this.port);
this.socket.addEventListener('error', function (ev) {
this.isConnected = false;
alert('Error connecting to websocket server, make sure it\'s running and port ' + this.port + ' is not occupied by other process');
}.bind(this));
this.socket.addEventListener('open', function (ev) {
this.isConnected = true;
this.socket.send(this.pluginName + ' connected to server!!!');
this.initSocketListeners();
this.stayConnected();
this.isAlive = true;
this.aliveInterval = setInterval(function () {
this.checkIfAlive();
}.bind(this), 2500);
this.getTabsToReload(function (tabsToReload) {
tabsToReload.forEach(function (tab) {
chrome.tabs.update(tab.id, {url: tab.url});
});
});
chrome.browserAction.setIcon({
path: {
"16": "img/icon_active_16.png",
"24": "img/icon_active_24.png",
"32": "img/icon_active_32.png"
}
});
}.bind(this));
},
disconnectFromServer: function () {
this.socket.close();
},
stayConnected: function () {
setTimeout(function () {
this.socket.send('ping');
if (this.isConnected) {
this.stayConnected();
}
}.bind(this), 1000);
},
checkIfAlive: function () {
this.isAlive = false;
setTimeout(function () {
console.log(this.isAlive)
if (!this.isAlive) {
console.log(this.isAlive)
this.disconnectFromServer();
}
}.bind(this), 2000);
},
init: function () {
this.setPort();
this.initListeners();
}
}
window.onload = new myPlugin();
这是我的节点模块代码:
"use strict";
//var WebSocketServer = require('websocketserver');
//var WebSocketServer = require("nodejs-websocket")
var WebSocket = require('ws');
class MyModule {
constructor(options) {
this.options = options;
this.server = false;
this.pluginName = 'Some';
this.isConnected = false;
this.connection = false;
this.init();
return this.refreshTab.bind(this);
}
init() {
var port = this.options ? this.options.port : false;
this.server = new WebSocket.Server({port: port || 8001});
this.server.on('connection', (websocket) => {
console.log('Connection open');
this.websocket = websocket;
this.isConnected= true;
this.initListeners();
});
}
refreshTab(uploadedFiles) {
if (this.isConnected) {
if (Array.isArray(uploadedFiles)) {
uploadedFiles.forEach(function (el) {
this.websocket.send(el.toString());
}.bind(this));
} else {
this.websocket.send(uploadedFiles ? uploadedFiles.toString() : 'reload');
}
} else {
console.log('You are not connected to server yet.');
}
}
initListeners() {
this.websocket.on('message', (message) => {
if (message == 'ping') {
this.websocket.send('pong');
}
});
this.websocket.on('close', () => {
this.isConnected = false;
console.log(this.pluginName + ' connection is closed');
});
}
};
module.exports = MyModule;
感谢任何帮助, 提前致谢。
所以我的问题实际上是 manifest.json
"background": {
"scripts": ["js/tab_reloader.js"],
"persistent": false
}
"persistent" 设置为 false,它将我的背景页面转换为事件页面。并且事件页面在一段时间后从内存中卸载,这正在终止连接。在我将 "persistent" 设置为 true 后问题得到解决。