Это 30-й день моего участия в августовском испытании обновлений. Узнайте подробности события:Испытание августовского обновления.
предисловие
Почему эта тема поднята?y.qq.com/QQ музыка,
- Плеер находится на отдельной странице
- Когда вы ищете песню, которая вас устраивает на другой странице, нажмите кнопку воспроизведения или добавьте в очередь воспроизведения.
- Вы обнаружите, что страница игрока отвечает отзывчивым ответом
Здесь я снова думаю о сцене с тележкой для покупок в торговом центре, и впечатление действительно улучшилось.
В начале я подозревал, что Web Socket — демон, но проанализировав сетевой запрос и посмотрев исходный код, не понял. Наконец-то обнаружил, что событие хранилища localStore — это демон, ха-ха.
Возвращаясь к теме, собственно, в случае нормальных запасов знаний, какие решения мы придумаем?
Забудьте следующее:
- Каждый опрос или длинный опрос сервера
- В соответствии с политикой одного и того же происхождения одна сторона принадлежит другой стороне.
opener
Демо и исходный код
Демонстрация многостраничного общения, для нормальной работы откройте его в последней версии браузера Chrome.
Адрес исходного кода демо
Связь между двумя браузерами Windows
WebSocket
Этому не так много объяснений, WebSocket — это протокол, предоставляемый HTML5 для полнодуплексной связи по одному TCP-соединению. Конечно, есть цена, и сервер нужно поддерживать.
js, который сейчас, конечно, более зрелый и стабильныйsocket.ioа такжеws, Есть также легкиеClusterWS.
ты сможешьThe WebSocket API (WebSockets) Узнайте больше о веб-сокетах.
Таймер + клиентское хранилище
Таймер: setTimeout/setInterval/requestAnimationFrame
Хранилище клиента: cookie/localStorage/sessionStorage/indexDB/файловая система Chrome.
О таймерах и о клиентской памяти сказать особо нечего.
- cookie: Будет приноситься на сервер каждый раз, и хранилище не большое, 4кб?не очень четко помню
- localStorage/sessionStorage должен быть 5 МБ, sessionStorage попрощается с вами после закрытия браузера.
- indexDB мощная штука, но чтение асинхронное, и он также может хранить файлы Blob, что действительно много.
- файловая система хрома,Filesystem & FileWriter API, в основном поддержка хрома и оперы. Эта штука — файловая система.
postMessage
Cross-document messagingУровень одобрения этой штуки составляет 98,9%. Кажется, он может отправлять файлы, ха-ха, мощно.
Но присмотритесь к window.postMessage(), и вам суждено сначала получить объект окна. Ему также суждено быть ограниченным в его использовании, и эти две формы должны быть связаны. Распространенные способы установления контакта:
- window.open
- window.opener
- iframe
Ссылаясь на вышеупомянутый window.open, после открытия вы можете получить дескриптор открытого окна и, конечно же, вы можете напрямую манипулировать окном.
Здесь я думаю, что общий интерфейсный персонал может думать, что программ должно быть выше трех.
Конечно же, поговорим о трех других способах, которые могут быть не так распространены.
StorageEvent
Page 1
localStorage.setItem('message',JSON.stringify({
message: '消息',
from: 'Page 1',
date: Date.now()
}))
Page 2
window.addEventListener("storage", function(e) {
console.log(e.key, e.newValue, e.oldValue)
});
Как и выше, страница 1 устанавливает сообщение, страница 2 регистрирует событие хранения, и вы можете отслеживать изменения данных.
е вышеStorageEvent, имеет следующие уникальные свойства (все только для чтения):
- key : Представляет, что имя свойства изменилось. При очистке методом clear() все имена свойств становятся нулевыми.
- newValue: новое добавленное значение. Значение равно null, если был выполнен метод clear() или имя ключа было удалено.
- oldValue: Исходное значение. Если был выполнен метод clear() или начальное значение не установлено до того, как будет установлено новое значение, будет возвращено значение null.
- storageArea: управляемый объект хранилища
- url: URL-адрес документа, в котором находится объект, ключ которого изменился
Broadcast Channel
Эта штука в основном используется для многооконности, можно использовать и Service Worker. Его поддерживают Firefox, Chrome и Opera. Иногда я действительно ненавижу Safari. Браузер поддерживает около 77%.
Его также очень просто использовать, создать BroadcastChannel, а затем прослушивать события. Только нужно обратить внимание на один момент, название канала должно быть одинаковым.
Page 1
var channel = new BroadcastChannel("channel-BroadcastChannel");
channel.postMessage('Hello, BroadcastChannel!')
Page 2
var channel = new BroadcastChannel("channel-BroadcastChannel");
channel.addEventListener("message", function(ev) {
console.log(ev.data)
});
SharedWorker
Это общий Worker после Web Worker, который может использоваться разными страницами.
MDN дает более полный пример здесьsimple-shared-worker.
Вот эпизод, Safari имеет несколько версий, которые поддерживают эту функцию, а потом нет, это все еще ваш Safari, это действительно 6.
Хотя собственные ресурсы SharedWorker являются общими, но чтобы добиться многостраничного общения друг с другом, ему все же нужно проделать некоторые хитрости. Давайте посмотрим на код самого ShareWoker на примере, предоставленном MDN:
onconnect = function(e) {
var port = e.ports[0];
port.onmessage = function(e) {
var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
port.postMessage(workerResult);
}
}
Вышеприведенный код на самом деле очень прост.Порт является ключом.Этот порт является мастером связи с каждой страницей.Поскольку ресурс SharedWorker является общим, с ним легко обращаться, просто сохраните порт.
Взгляните на следующий измененный код:
SharedWorker становится издателем исключительно по подписке, ха-ха.
var portList = [];
onconnect = function(e) {
var port = e.ports[0];
ensurePorts(port);
port.onmessage = function(e) {
var data = e.data;
disptach(port, data);
};
port.start();
};
function ensurePorts(port) {
if (portList.indexOf(port) < 0) {
portList.push(port);
}
}
function disptach(selfPort, data) {
portList
.filter(port => selfPort !== port)
.forEach(port => port.postMessage(data));
}
MessageChannel
API обмена сообщениями каналаMessageChannel
Интерфейс позволяет нам создать новый канал сообщений и передать два егоMessagePort
свойство для отправки данных.
Сначала необходимо установить соединение через postMessage.
Основное использование MessageChannel:
var channel = new MessageChannel();
var para = document.querySelector('p');
var ifr = document.querySelector('iframe');
var otherWindow = ifr.contentWindow;
ifr.addEventListener("load", iframeLoaded, false);
function iframeLoaded() {
otherWindow.postMessage('Hello from the main page!', '*', [channel.port2]);
}
channel.port1.onmessage = handleMessage;
function handleMessage(e) {
para.innerHTML = e.data;
}
Что касается онлайн-примера, у MDN официально есть версияСвязь по каналу сообщений
напиши в конце
Если вы считаете, что это хорошо, ваши лайки и комментарии — самая большая мотивация для меня двигаться вперед.
Цитировать
MDN Web Docs - Broadcast Channel
BroadcastChannel | Can I Use
broadcast-channel
StorageEvent
SharedWorker
simple-shared-worker
SharedWorker | Can I Use
Общий поток
feature-shared-web-workers Сводка связи между двумя окнами браузера