2012-02-17 10 views
21

Shared Web Workers được thiết kế để cho phép nhiều trang từ cùng một trang web (gốc) chia sẻ một Web Worker duy nhất.Các công nhân Web chia sẻ tồn tại trên một trang tải lại, liên kết điều hướng

Tuy nhiên, không rõ ràng với thông số (hoặc các hướng dẫn và thông tin khác về Người lao động được chia sẻ) cho dù Công nhân được chia sẻ sẽ vẫn tồn tại nếu bạn chỉ có một cửa sổ/tab từ trang web và bạn điều hướng đến một trang khác trên cùng một trang trang web.

Điều này sẽ hữu ích nhất trong trường hợp kết nối WebSocket từ Công nhân được chia sẻ vẫn được kết nối khi trang web được điều hướng. Ví dụ, hãy tưởng tượng một mã cổ phiếu hoặc khu vực trò chuyện sẽ tồn tại (mà không phải kết nối lại WebSocket) ngay cả khi trang web được điều hướng.

+0

Sự kiện lưu trữ hiện tại là lựa chọn tốt nhất của bạn cho điều đó, nhân viên được chia sẻ có thể sau này ... http://stackoverflow.com/questions/19125823/how-is-it-possible-to-share-single-js-resource -between-browser-tabs/19165781 # 19165781 – inf3rno

Trả lời

20

Tôi đã thực hiện một số thử nghiệm để tìm ra câu trả lời cho điều này trong thực tế.

Firefox chưa hỗ trợ tạo kết nối WebSocket từ Web Worker: https://bugzilla.mozilla.org/show_bug.cgi?id=504553 Vì vậy, Firefox không liên quan cho đến khi lỗi đó được giải quyết.

IE 10 không có support for Shared Web Workers do đó không có liên quan. Vì vậy, để lại Chrome.

Dưới đây là ví dụ để kiểm tra công nhân web được chia sẻ.

Đầu HTML:

<!DOCTYPE html> 
<html> 
<body> 
    <a href="shared.html">reload page</a> 
    <script> 
     var worker = new SharedWorker("shared.js"); 
     worker.port.addEventListener("message", function(e) { 
      console.log("Got message: " + e.data); 
     }, false); 
     worker.port.start(); 
     worker.port.postMessage("start"); 
    </script> 
</body> 
</html> 

Sau đó, việc thực hiện của người lao động chia sẻ bản thân trong shared.js:

var connections = 0; 

self.addEventListener("connect", function(e) { 
    var port = e.ports[0]; 
    connections ++; 
    port.addEventListener("message", function(e) { 
     if (e.data === "start") { 
      var ws = new WebSocket("ws://localhost:6080"); 
      port.postMessage("started connection: " + connections); 
     } 
    }, false); 
    port.start(); 
}, false); 

Kết quả thử nghiệm trong Chrome 20 (câu trả lời):

Khi trang được tải đồng thời trong hai tab riêng biệt, số lượng kết nối tăng lên mỗi khi một trong các trang được tải lại hoặc liên kết tự tham chiếu được nhấp.

Nếu chỉ có một phiên bản duy nhất của trang được tải thì số kết nối không bao giờ thay đổi khi trang được tải lại hoặc liên kết được nhấp.

Vì vậy, trong Chrome 20: Công nhân Web được chia sẻ không duy trì tải lại trang và nhấp chuột điều hướng liên kết.

+1

+1 để thử nghiệm – stimms

+0

Nếu tôi tải lại trang hoặc mở trang mới - SharedWorker sẽ được tạo lại? Tôi viết console.log (new Date(). GetTime()); Và thời gian luôn hiển thị khác nhau trong bảng điều khiển, sau khi tải lại trang. Vì vậy, luôn luôn tạo ra một cá thể WebSocket mới sau khi tải lại trang, đúng không? –

4

Có vẻ như đây là vấn đề cơ bản giống như the question 'What happens to an HTML5 web worker thread when the tab is closed while it's running?'. Tôi nghĩ rằng phần quan trọng của spec là this statement:

đại lý Người dùng có thể gọi là "giết chết một công nhân" mô hình xử lý trên một công nhân bất cứ lúc nào, ví dụ theo yêu cầu của người dùng, để đáp ứng quản lý hạn ngạch CPU hoặc khi nhân viên dừng hoạt động cần thiết công nhân nếu nhân viên tiếp tục thực hiện ngay cả sau khi cờ kết thúc được đặt thành true.

Một 'active needed worker' được định nghĩa như sau:

Một công nhân được cho là một nhân viên cần thiết hoạt động nếu một trong các tài liệu đối tượng trong tài liệu của người lao động đang hoạt động đầy đủ.

Vì vậy, như tôi hiểu, nếu tất cả các cửa sổ tham chiếu đến một công nhân sẽ bị đóng thì trình duyệt yêu cầu phải chấm dứt công nhân, nhưng không phải ngay lập tức. Tùy thuộc vào nó bền bỉ do đó sẽ không đáng tin cậy ngay cả khi nó xuất hiện để làm việc đôi khi.

Trong ví dụ của bạn, cách tiếp cận của tôi là tải toàn bộ trang web bằng Ajax - bạn sẽ không thể chạy Web Worker nếu người dùng của bạn đã tắt JS dù sao đi nữa, sau đó sử dụng History API để làm cho địa chỉ trang của người dùng tương ứng với trang thực tế (duy trì công cụ tìm kiếm và khả năng tương thích không phải JS).

+0

Câu hỏi của tôi là liệu việc chuyển đổi (nhấp liên kết) từ trang này sang trang khác trên cùng một trang * (hoặc tải lại cùng một trang web) sẽ chuyển công nhân đó thành một hoạt động không cần thiết nhà nước, và liệu điều này có làm cho nó bị giết. Nói cách khác, nó có chuyển từ hoạt động sang hoạt động hay nó chuyển sang không hoạt động trước khi trang tiếp theo tải (và nếu nó đủ dài để quan trọng)? Đây thực sự là một câu hỏi về những gì trình duyệt thực sự làm và ý định là gì. Các từ ngữ spec chính nó là mơ hồ, đó là lý do tại sao tôi yêu cầu. – kanaka

+1

@kanaka Có, dỡ bỏ trang di chuyển nó đến một trạng thái mà nó sẽ bị giết (xem [bước 5] (http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html # run-a-worker)), nhưng spec không yêu cầu nó bị giết ngay lập tức. Như tôi đã nói, thỉnh thoảng nó có thể hoạt động, nhưng không mong đợi nó đáng tin cậy. Nếu bạn muốn biết những gì trình duyệt thực sự làm, hãy thử nó. – robertc

3

Tôi đã thành công với một kỹ thuật hơi xoay vòng, khi tôi muốn chuyển sang trang tiếp theo nhưng vẫn duy trì SharedWorker, tôi mở một cửa sổ bật lên (hy vọng không phô trương) tạo cùng một công nhân, đợi nó hoạt động và gửi thư đến cổng/cửa sổ ban đầu, sau đó điều hướng đến trang mới và sau đó, khi trang đó tải, hãy đóng cửa sổ bật lên. Chiến lược này duy trì ít nhất một kết nối hoạt động mọi lúc, vì vậy công nhân không bao giờ quyết định ngừng hoạt động.

Kỹ thuật này có vẻ khá mạnh mẽ cho đến nay. Mặc dù nhìn thấy cửa sổ bật lên hơi khó chịu nhưng đó là một sự thỏa hiệp hợp lý đối với một số trường hợp sử dụng.

+0

Bạn có thể cho tôi xem ví dụ của bạn được không. Tôi luôn tạo một trang mới ngay cả sau khi tải lại trang. –