2016-03-22 25 views
1

Dizini görüntülemek ve değiştirmek için indexedDB-Wrapper Dexie, birkaç jQuery-Libraries ve syncfusions eGrid kullanan bir chrome uzantısı üzerinde çalışıyorum. Bu sorunun daha önce birkaç kez sorulduğunu biliyorum, ama şimdi garip davranışları keşfettim.Çoklu chrome.runtime.onMessage-Listeners - bağlantısız bağlantı noktası hatası

Benim Kurulumu: (a web enjekte)

  • background-betik
  • içerik komut
  • index.html (Izgara göstermek için)
  • manifest.json

Uzantımı yeniden yüklediğimde her şey yolunda. İçerik komut dosyam ile kaydırılabilir bir ad listesi enjekte ediyorum. Bu, sekmeyi yeniden yüklerken de çalışır. Ancak 'dan (resmi belgelerde popup.html) önce index.html'yi açtığımda arka plan komut dosyasındaki sendResponse bir süre sonra çalışmayı durdurur. Sekmeyi yeniden yüklemek o zaman yardımcı olmaz. Saatlerce araştırıyordum, bu problemin zaten düzeltildiğini iddia ettikleri googles bugtracker'da birçok benzer durum ve bazı entrikler buldum. Ayrıca indexedDB gibi async fonksiyonlarına sahip olduğumda getiri kullanmam gerektiğini biliyorum.

Size daha fazla bilgi vermek için kısaltılmış komut dosyalarınızı listelerim.

Content-Senaryo

chrome.runtime.sendMessage({greeting: 'getNames'},function(response){ 
    $('.names-container').append(response.farewell); 
}); 
chrome.runtime.sendMessage({greeting: 'getData'+name},function(name){ 
    chrome.runtime.sendMessage({greeting: 'delete'},function(response){ 
     console.log(response.farewell); 
    }); 
    chrome.runtime.sendMessage({greeting: 'set'}, function(response) { 
     console.log(response.farewell); 
    }); 
}); 

Arkaplan-Senaryo

chrome.runtime.onMessage.addListener(function(message,sender,sendResponse){ 
    if(message.greeting == 'getNames'){ 
    // Get array of names from idb and send it back 
    idb.opendb().then(function(a){ 
     sendResponse(a); 
    }); 
    return true; 
    } else if(message.greeting.indexOf('getData') >= 0){ 
    // get more information for selected name 
    idb.opendb().then(function(a){ 
     sendResponse(a); 
    }); 
    return true; 
    } else if(message.greeting == 'delete'){ 
    // further processing to delete some stuff 
    idb.opendb().then(function(a){ 
     sendResponse(a); 
    }); 
    return true; 
    } else if(message.greeting == 'set'){ 
    // synchronous function 
    // do something ... 
    return false; 
    } else { 
    // Do something 
    } 
    //return true; 
}); 

funtion indexhtml(){ 
    chrome.runtime.sendMessage(
    "notifications", 
    function (response) { 
     console.log(response); 
    } 
); 
} 

Index.html

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){ 
    if(request == 'notifications'){ 
    notifications(); 
    } 

    sendResponse("Message received from background-page for "+request); 
}); 

Manifest

{ 
    "manifest_version": 2, 
    "name": "MyExtension", 
    "description": "Some desc...", 
    "version": "0.2", 
    "background": { 
     "scripts": ["js/jquery-2.1.4.min.js", "js/background.js", "...", 
     "persistent": true 
    }, 
    "default_locale": "en", 
    "content_scripts": [ 
     { 
      "matches": ["<all_urls>"], 
      "js": ["js/jquery-2.1.4.min.js"] 
     }, 
     { 
      "matches": ["https://domain.tld/*"], 
      "js": ["js/jquery-2.1.4.min.js", "js/contentscript.js"], 
      "css" : ["css/contentscript.css", 
      "run_at": "document_start" 
     } 
    ], 

    "icons": { 
     "16": "images/icon-16x16.png", 
     "48": "images/icon-48x48.png", 
     "128": "images/icon-128x128.png" 
    }, 
    "browser_action": { 
     "default_icon": "images/icon-128x128.png" 
    }, 
    "permissions": [ 
     "cookies", "tabs", "alarms", "webRequest", "webRequestBlocking", 
     "contextMenus", "<all_urls>", "storage" 
    ], 

    "content_security_policy": "script-src 'self' 'unsafe-eval'; 
    object-src 'self'" 
} 

Tam olarak ne zaman hata Attempting to use a disconnected port object görünür biliyor veremeyiz çünkü ben, bu davranışı hata ayıklamak için zor olduğunu. SendResponse yürütüldükten ve index.html açılmışsa bağlantı noktasının doğru kapanmadığı anlaşılıyor.

Son olarak kısaltılmış Hata-Mesaj:

Error: Attempting to use a disconnected port object 
    at Error (native) 
    at PortImpl.postMessage (extensions::messaging:65:22) 
    at Port.publicClass.(anonymous function) [as postMessage] (extensions::utils:94:26) 
    at responseCallback (extensions::messaging:163:16) 

idb-Fonksiyonlar burada yazmış gibi özelleştirilmiş ve Yapmayacağım çalışma vardır, ama sadece Özür orada ne yaptığını göstermek istiyorum. Sonuç elde edildiğinde .then()sendReponse kullanıyorum ve return true; eşanlamlı ise sonucu beklemek için kullanıyorum. Ayrıca onMessage ve sendMessage için her betiği aradım. OnMessage/sendMessage ile ilgili listelenen işlevler kullanıyorum, başka bir yerde kullanılmazlar. Bildirimleri içeren bir diziyi belirli bir aralıkta kaydetmek ve sonra bildirimleri yeniden yüklemek için index.html işlevini çalıştırmak için indexhtml() için bir zamanlayıcı kullanıyorum.

Dizin.,

chrome.browserAction.onClicked.addListener(function(tab){ 
    chrome.tabs.create({url: chrome.extension.getURL('index.html')}); 
}); 

cevap

3

Tamam ben daha hata ayıklama ekledikten sonra başıma cevap buldu: html Tab browserAction aracılığıyla açılan alır. Sorun şu ki, çoklu (2) onMessage-Listener kullanıyorum. Sadece içerik sayfama (index.html) gönderilen mesajların dinleneceği belirli bir dinleyici yoktur. Index.html dosyasını her açtığımda, içerik yazılamamda sendMessage kullanıldıysa, ek onMessage-Listener ilk olarak çağrılacaktı. Index.html'ye gömülü olan bu onMessage-Listener'ın her seferinde de çağrıldığının farkında değildim. Daha sonra içerik-betiğimde - aynı sonuç ile sendMessage için hedefi değiştirdim.

Not: Bu konu hakkında googles belgelerinde bir not da vardır birden çok sayfa onMessage olaylar için dinliyorsanız, yalnızca ilk yanıt göndermeden başarılı olacağı belirli bir etkinlik için sendResponse() aramak için. Bu olaya verilen diğer tüm cevaplar dikkate alınmayacaktır.

Link here

ikinci sorunu ben dışarıda eğer maddesi ve her çağrıldım bu yoldan sendResponse kullanılan idi. Sonunda sadece sendResponse'yi if-cümlesi içine koymak zorunda kaldım, böylece sadece arka plan sayfasından belirli bir mesajın sendMessage yoluyla çağrılması durumunda çağrılır.

Arkaplan-Senaryo

  • krom uzantısı arayarak tab.id olsun:
  • sadece
index.html göndermek //extid/index.html
chrome.windows.getAll({populate:true},function(windows){ 
    windows.forEach(function(window){ 
    window.tabs.forEach(function(tab){ 
     if(tab.url.indexOf(chrome.extension.getURL('index.html')) >= 0){ 
     chrome.tabs.sendMessage(tab.id,{ greeting: "notifications"}, function(response){ 
      console.log(response); 
     }); 
     } 
    }); 
    }); 
}); 

Index.html

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse){ 
     if(message.greeting == "notifications-trades"){ 
      Notifications(); 
      sendResponse("Message received from bg "+message.greeting); 
      //if async add return true; 
     } else { 
      //Do something 
     } 
});