2015-05-11 33 views
5


WebApp ile ilgili ServiceWorker arasında PostMessage'ı göndermeyi denerim. ServiceWoker başarıyla kaydedildi ve şu ana kadar çalışıyor.
Ne yazık ki bazı garip davranışlar fark ettim:
1. navigator.serviceWorker.controller her zaman boştur.Chrome ServiceWorker postMessage

self.addEventListener('message', function (evt) { 
console.log('postMessage received', evt); 
}); 

Maalesef önemli alan geri kökeni evt.origin göndermek için = ““ve evt.source = null istenen değer içermeyen: ServiceWorker tarafında
2. Ben postMessage bu şekilde uyguladı. Ama her zaman gönderilen evt.data'yı alırım.

Nasıl posta gönderileceğini biliyor musunuz?

Çok teşekkür ederim!
Andi

+0

Navigator.serviceWorker.controller öğesinin her zaman boş olduğu aynı sorunu yaşıyorum. Seçilen cevap bu sorunu çözmüyor gibi görünüyor - nasıl çözdünüz? –

cevap

10

Bir geri this demo gösterilir ve aslında henüz bu test etmedim şu şekilde (yapılmaktadır kontrollü app işçinin bir yanıt göndermek için bir yol, ama demo iyi çalışıyor ve kod görünüyor şartnamelere katılıyorum). Ana sayfada

:

self.addEventListener('message', function(event) { 
    event.ports[0].postMessage({'test': 'This is my response.'}); 
}); 

Daha sonra birlikte istediğini yapmak sendMessage işlevi tarafından döndürülen sözünü kullanmak mümkün olmalıdır:

function sendMessage(message) { 
    // This wraps the message posting/response in a promise, which will 
    // resolve if the response doesn't contain an error, and reject with 
    // the error if it does. If you'd prefer, it's possible to call 
    // controller.postMessage() and set up the onmessage handler 
    // independently of a promise, but this is a convenient wrapper. 
    return new Promise(function(resolve, reject) { 
    var messageChannel = new MessageChannel(); 
    messageChannel.port1.onmessage = function(event) { 
     if (event.data.error) { 
     reject(event.data.error); 
     } else { 
     resolve(event.data); 
     } 
    }; 

    // This sends the message data as well as transferring 
    // messageChannel.port2 to the service worker. 
    // The service worker can then use the transferred port to reply 
    // via postMessage(), which will in turn trigger the onmessage 
    // handler on messageChannel.port1. 
    // See 
    // https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage 
    navigator.serviceWorker.controller.postMessage(message, [messageChannel.port2]); 
    }); 
} 

Ve hizmet işçisi kodunda

Servis çalışanından gelen cevap.

+0

Çok teşekkür ederim. Tam olarak ihtiyacım olan şey buydu. Şuan çalışıyor! – user24502

+0

Birden çok müşteriye mesaj gönderme hakkında ne düşünüyorsunuz? Örneğin, tüm komut dosyalarının ayrıştırıldığını ve çalıştırıldığını söyleyen 'init' mesajı durumunda? –

+3

İlk iletiyi göndermeden tek yönlü iletişim yapmanın bir yolu var - Servis çalışanından istemciye her 'yükleme' olayına bir ileti göndermek istiyorum (istemcinin ilk iletiyi göndermesi gerekmeden) –

4

@GalBracha, önce bir mesaj göndermeden müşteriyle iletişime geçip geçemeyeceğinizi soruyordu - evet !. İtme bildirimi alındığında (kullanıcı bildirimi tıkladığında değil, hizmet çalışanı olayı aldığında değil) istemcilere bir ileti göndermek istediğimde bunu nasıl yaptığımı hızlı bir örnek:

bazı olay (belki yüklemek olay) için hizmet işçinin içinde

// navigator.serviceWorker.addEventListener('message', ...) should work too 
navigator.serviceWorker.onmessage = function (e) { 
    // messages from service worker. 
    console.log('e.data', e.data); 
}; 

, cevaben: (hizmet işçisi kayıt, vb sonra) istemci js (? besbelli)

// find the client(s) you want to send messages to: 
self.clients.matchAll(/* search options */).then((clients) => { 
    if (clients && clients.length) { 
     // you need to decide which clients you want to send the message to.. 
     const client = clients[0]; 
     client.postMessage("your message"); 
    } 

hiledir için mesaj olayına ilişkin dinleyicinizi serviceWor’üne ekleyin Ker nesnesi, pencere nesnesi değil.

+1

@GalBracha: Ayrıca bkz. Https://stackoverflow.com/a/35108844/271577 (bir (denetlenmemiş) kayıt sayfasına geri gönderiliyorsa, 'includeUncontrolled 'seçeneği yardımcı olabilir.) –