2015-05-11 14 views
5


Tôi cố gắng gửiMessage giữa WebApp và ServiceWorker tương ứng. ServiceWoker đã được đăng ký và làm việc thành công cho đến nay.
Thật không may tôi nhận thấy một số hành vi lạ:
1. navigator.serviceWorker.controller luôn là rỗng.
2. Ở phía ServiceWorker tôi thực hiện postMessage theo cách này:Dịch vụ ChromeLàm việc bằng bưu điệnMessage

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

Thật không may là lĩnh vực quan trọng để gửi trở lại nguồn gốc evt.origin = ““và evt.source = null không chứa các giá trị mong muốn. Nhưng tôi luôn nhận được evt.data đã gửi.

Bạn có biết cách đăng lại không?

Cảm ơn bạn rất nhiều!
Andi

+0

Tôi có cùng một vấn đề khi navigator.serviceWorker.controller luôn là rỗng. Câu trả lời đã chọn dường như không giải quyết được vấn đề đó - bạn giải quyết nó như thế nào? –

Trả lời

10

Một cách để gửi một phản hồi từ người lao động trở lại ứng dụng kiểm soát được trình bày trong this demo và được thực hiện theo cách sau (tôi đã không thực sự thử nghiệm này, nhưng bản demo hoạt động tốt và mã dường như để đồng ý với thông số kỹ thuật).

Trong trang chính:

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]); 
    }); 
} 

Và trong mã nhân viên dịch vụ:

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

Sau đó, bạn sẽ có thể sử dụng lời hứa trả về bởi các sendMessage chức năng để làm những gì bạn muốn với phản hồi đến từ nhân viên dịch vụ.

+0

Cảm ơn bạn rất nhiều. Đó chính là điều tôi cần. Nó hoạt dộng bây giờ! – user24502

+0

Làm cách nào để gửi tin nhắn cho nhiều khách hàng? Ví dụ trong trường hợp của thông điệp 'init' nói rằng tất cả các tập lệnh được phân tích cú pháp và thực thi? –

+3

Có cách nào để thực hiện giao tiếp một chiều mà không gửi tin nhắn đầu tiên - Tôi muốn gửi một tin nhắn trên mỗi sự kiện 'cài đặt' từ nhân viên dịch vụ đến máy khách (mà không cần khách hàng gửi tin nhắn đầu tiên) –

4

@GalBracha hỏi xem bạn có thể liên lạc với khách hàng mà không cần gửi tin nhắn lần đầu tiên - có !. Dưới đây là ví dụ nhanh về cách tôi đã thực hiện khi tôi muốn gửi thư cho khách hàng khi nhận được thông báo đẩy (không phải khi người dùng nhấp vào thông báo, nhưng khi nhân viên dịch vụ nhận được sự kiện):

js khách hàng (sau khi đăng ký lao động dịch vụ, vv):

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

trong lao động dịch vụ của bạn, để đáp ứng với một số sự kiện (có lẽ là sự kiện cài đặt): (? rõ ràng)

// 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"); 
    } 

thủ đoạn này là đính kèm người nghe của bạn cho sự kiện tin nhắn đến serviceWor đối tượng ker, không phải đối tượng cửa sổ.

+1

@GalBracha: Xem thêm https://stackoverflow.com/a/35108844/271577 (nếu đăng lại trang đăng ký (không được kiểm soát), tùy chọn 'includeUncontrolled' có thể giúp ích.) –

Các vấn đề liên quan