问题
I am creating a chrome app (packaged) and I have to create a UDP socket and listen for the incoming broadcast messages as soon as chrome browser starts up.
Everything works fine as I start browser , I get the callback registered through chrome.sockets.udp.onReceive.addListener()
API and the data as well.
The problem starts when the event page is unloaded (after about 10-15 secs).
Any new UDP packets are not received.
But as seen in Chrome Apps & Extensions Developer Tool
, onReceive
callback triggered once even after the event page is unloaded (but not for subsequent UDP packets),but it doesn't hit my callback function.
And I have kept the persistent
flag true while creating the UDP socket.
Here is the manifest of my app:
{
"manifest_version": 2,
"name": "App Name",
"description": "Description",
"version": "1.0",
"app": {
"background": {
"scripts": ["socket.js","eventPage.js"],
"persistent": true
}
},
"sockets":{
"udp": {"send":["*:*"], "bind":["*:*"]}
},
"permissions":["system.network","notifications"]
}
Event page and socket code:
// eventPage.js
chrome.runtime.onStartup.addListener(function() {
console.log("I started up!");
socket.cleanup_create();
});
chrome.runtime.onSuspend.addListener(function() {
console.log("I am being suspended!");
});
// socket.js
function show(jsontext) {
var json_object = JSON.parse(jsontext);
console.log(json_object.TitleText);
console.log(json_object.MainText);
chrome.notifications.create("",
{type:'basic',iconUrl:'icon.png',title:json_object.TitleText,message:json_object.MainText},
function callback(){})
}
var socket = {
socketId:null,
/*==========Receive Callback=================*/
recieve_callback:function(rc){
console.log("Received on socket ID "+rc.socketId);
var dataView = new DataView(rc.data);
var decoder = new TextDecoder("utf-8");
var decodedString = decoder.decode(dataView);
console.log("Data Received and it is "+decodedString);
show(decodedString);
},
/*==========Receive Error Callback=================*/
recieve_error_callback:function(info){
console.log("Error on socket with code "+info.resultCode);
},
/*==========Bind Callback=================*/
bind_cb: function(s){
console.log("Socket seems to be binded result "+s);
chrome.sockets.udp.onReceive.addListener(socket.recieve_callback)
chrome.sockets.udp.onReceiveError.addListener(socket.recieve_error_callback)
},
/*==========Create Callback=================*/
create_cb: function(s){
console.log("Socket seems to be created id is "+s.socketId);
socket.socketId = s.socketId;
chrome.sockets.udp.bind(socket.socketId,"0.0.0.0",8080,socket.bind_cb);
},
/*==========Create Method=================*/
create: function(){
chrome.sockets.udp.create({persistent:true,name:"udp_socket",bufferSize:15000},socket.create_cb);
},
cleanup_create:function(){
chrome.sockets.udp.getSockets(function cleanup_create_cb(socketInfos){
console.log("Cleaning up existing sockets "+socketInfos.length);
for (i = 0; i < socketInfos.length; i++) {
chrome.sockets.udp.close(socketInfos[i],function socket_close_cb(){});
}
socket.create();
});
}
};
Is there any way I can keep the event page always loaded or any other means through which I can ensure that I always get the onReceive
event?
回答1:
How do Chrome event pages work? Here's the documentation, but in a nutshell:
- Your page's top level context executes, registering listeners for events.
- Chrome builds a list of events that it should wake the page for.
- Page unloads: note that it completely destroys JS context, including listeners and any objects initialized (e.g. your
socket
object). - Event happens. Chrome looks up if it needs to wake up your page. Suppose it does.
- The page is loaded again, listeners register again, and then Chrome calls them.
To quote the docs:
Because the listeners themselves only exist in the context of the event page, you must use
addListener
each time the event page loads; only doing so atruntime.onInstalled
by itself is insufficient.
Now let's look at this line:
// Called in a callback to chrome.sockets.udp.bind()
bind_cb: function(s){
/* ... */
chrome.sockets.udp.onReceive.addListener(socket.recieve_callback)
/* ... */
}
When the page is loaded again, this does not execute synchronously. Therefore, at step 5, Chrome fails to find an appropriate listener and it's not called.
Do note that the event is global, i.e. it's not bound to a socket object (that does not exist after unloading). So you can (and should) safely bind it to one function that analyzes the callback parameters to understand which socket it operates on.
So, to make your code work, addListener
must be called synchronously when the event page loads.
来源:https://stackoverflow.com/questions/28393684/not-getting-onreceive-callback-for-udp-socket-on-chrome-after-event-page-is-unlo