我尝试为Chromebook创建的应用(Chrome OS 60.0.3112.114 64位)侦听UDP广播,当此类消息到达时,我希望它打开一个窗口。到目前为止,当JS被添加到窗口时,一切都很好,但是应用程序的目的是安静地收听消息,只有在收到消息后才会打开窗口。
所有代码都已移至background.js,现在它从未收到ouside消息。首先想到的是它被暂停,所以我在background.js中添加了一个setInterval来向我自己发送数据,模拟外部数据到达并正确接收这些消息,脚本没有休眠。当我创建任何类型的窗口时,魔法开始,我立即开始接收广播。当我关闭窗口时外部数据被中断,我仍然可以从setInterval发送所有自己的消息。
这有什么解决方案吗?我试图做的下一件事是创建一个隐藏的窗口,但没有这样的东西,也尝试使用background.html并在background.js代码中放置iframe将导致相同的行为。
的manifest.json
{
"name": "UDP Sample",
"description": "Can't receive data",
"version": "0.1",
"manifest_version": 2,
"app": {
"background": {
"scripts": ["background.js"],
"persistent": false
}
},
"icons": {
"16": "calculator-16.png",
"128": "calculator-128.png"
},
"sockets": {
"udp": {
"send": "*",
"bind": "0.0.0.0:13000"
}
},
}
background.js:
chrome.app.runtime.onLaunched.addListener(StartApp);
var socketId;
function StartApp()
{
console.log('app started');
chrome.sockets.udp.onReceive.addListener(SockRecv);
chrome.sockets.udp.onReceiveError.addListener(SockError);
SockBind(AppReady, AppError);
}
function AppReady()
{
setInterval(function()
{
console.log("self sending data");
var buf = new Uint8Array([70, 73, 82, 69]);
SockSend(false, buf.buffer);
}, 4000);
console.log('listening for net events.');
}
function AppError()
{
console.log('bind failed, retrying in 10 seconds.');
setTimeout(StartApp, 10000);
}
function LaunchWindow()
{
chrome.app.window.create('about.html',
{
frame: "none",
resizable: false,
outerBounds: {
'width': 400,
'height': 300
}
});
}
function SockRecv(info)
{
console.log("data received " + info.remoteAddress + " bytes");
if (info.socketId !== socketId || info.remoteAddress == '127.0.0.1')
return;
LaunchWindow();
}
function SockSend(ip,data)
{
chrome.sockets.udp.send(socketId, data, '127.0.0.1', 13000, function()
{
console.log("data sent");
});
}
function SockError(info)
{
console.log("something bad happened");
if (info.socketId !== socketId)
return;
chrome.sockets.udp.setPaused(socketId, false, function(){});
}
function SockBind(ready_func, error_func)
{
// Create the Socket
chrome.sockets.udp.create({persistent: true},
function(socketInfo)
{
console.log("new socket created");
socketId = socketInfo.socketId;
try
{
chrome.sockets.udp.bind(socketId, "0.0.0.0", 13000, function(result)
{
if (result < 0)
{
result = socketId;
socketId = false;
chrome.sockets.udp.close(result, error_func);
}
else
ready_func();
});
}
catch(err)
{
error_func();
}
});
}
控制台调试(我手动执行函数LaunchWindow,突然外部数据到达):
background.js:7 app started
background.js:80 new socket created
background.js:25 listening for net events.
background.js:19 self sending data
background.js:61 data sent
background.js:49 data received 127.0.0.1 bytes
background.js:19 self sending data
background.js:61 data sent
background.js:49 data received 127.0.0.1 bytes
background.js:19 self sending data
background.js:61 data sent
background.js:49 data received 127.0.0.1 bytes
LaunchWindow()
undefined
background.js:49 data received 192.168.1.49 bytes
background.js:19 self sending data
background.js:61 data sent
background.js:49 data received 127.0.0.1 bytes
background.js:49 data received 192.168.1.49 bytes
background.js:19 self sending data
background.js:61 data sent
background.js:49 data received 127.0.0.1 bytes
background.js:49 data received 192.168.1.49 bytes
background.js:19 self sending data
netstat -l的输出证明套接字正在等待数据:
chronos@localhost / $ netstat -l
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:ssh 0.0.0.0:* LISTEN
tcp6 0 0 [::]:ssh [::]:* LISTEN
udp 0 0 0.0.0.0:13000 0.0.0.0:*
udp 0 0 0.0.0.0:bootpc 0.0.0.0:*
udp 0 0 0.0.0.0:mdns 0.0.0.0:*
udp 0 0 0.0.0.0:mdns 0.0.0.0:*
udp6 0 0 [::]:mdns [::]:*
答案 0 :(得分:0)
ChromeOS有一个防火墙,可以防止侦听套接字在没有活动的应用程序窗口时接受新连接。
我发现,最好的解决方案是创建一个 prepareAd();
ScheduledExecutorService scheduler =
Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new Runnable() {
public void run() {
Log.i("Hello", "World");
runOnUiThread(new Runnable() {
public void run() {
if (mInterstitialAd.isLoaded()) {
mInterstitialAd.show();
} else {
Log.d("TAG", "The interstitial wasn't loaded yet.");
}
prepareAd();
}
});
}
}, 55, 285,TimeUnit.SECONDS);
}
public void prepareAd() {
mInterstitialAd = new InterstitialAd(this);
mInterstitialAd.setAdUnitId("ca-app-pub-3940256099942544/1033173712");
mInterstitialAd.loadAd(new AdRequest.Builder().build());
}
类型的窗口,它不是隐藏的,而是最小化的。您可以使用https://github.com/kzahel/connection-forwarder查看示例实现,或在网上商店中查看演示:https://chrome.google.com/webstore/detail/connection-forwarder/ahaijnonphgkgnkbklchdhclailflinn