2015-03-27 8 views
7

Я использую стек MEAN (mongo, express, угловой и узел). Я часто отношусь к производству ... каждые пару дней. Меня беспокоит, что я время от времени меняю клиентский код и API, и я бы предпочел не обеспечивать обратную совместимость API с предыдущими версиями кода клиента.Как принудительно перезагрузить клиент после развертывания?

В таком сценарии, что является наиболее эффективным способом обеспечения перезагрузки всех клиентов при нажатии на производство? Я видел, что Evernote, например, имеет всплывающее окно, которое говорит что-то вроде этого, перезагрузите браузер для последней версии Evernote. Я хотел бы сделать что-то похожее ... мне нужно идти по пути socket.io или sock.js, или я пропустил что-то простое, и есть более простой способ добиться этого?

ответ

7

Обновление: AppCache был устаревшим летом 2015 года, поэтому нижеследующее не является лучшим решением. Новая рекомендация заключается в том, чтобы вместо этого использовать Service Workers. Тем не менее, работники службы в настоящее время все еще экспериментальны с отрывочной (читаемой: возможно, нет) поддержкой в ​​IE и Safari.

В качестве альтернативы, многие инструменты сборки теперь без проблем включают в себя функции кэширования кеша и файлы «управление версиями» для решения вопроса OPs. WebPack, возможно, является нынешним лидером в этом пространстве.


Это может быть хороший случай использования для использования в HTML5 AppCache

Вы, вероятно, хотите автоматизировать некоторые из этих шагов в ваших сценариях развертывания, но здесь есть некоторый код, вы могли бы найти полезным, чтобы вы начал.

Сначала создайте файл манифеста appcache. Это также позволит вам кэшировать ресурсы в браузере клиента, пока вы явно не измените дату файла манифеста appcache.

/приложение.AppCache:

CACHE MANIFEST 

#v20150327.114142 

CACHE: 
/appcache.js 
/an/image.jpg 
/a/javascript/file.js 
http://some.resource.com/a/css/file.css 

NETWORK: 
* 
/

В app.appcache, комментарий на линии #v20150327.114142 как мы указываем броузеру, что манифест изменилось и ресурсы должны быть перезагружен. Это может быть что угодно, если файл будет отличаться от браузера предыдущей версии. Во время развертывания нового кода в вашем приложении эта строка должна быть изменена. Также можно использовать идентификатор сборки.

Во-вторых, на всех страницах, которые вы хотите использовать AppCache, изменить тег заголовка, как, например:

<html manifest="/app.appcache"></html> 

Наконец, вам нужно добавить некоторые JavaScript, чтобы проверить AppCache каких-либо изменений, и если есть, что-то с этим поделать. Вот Angular module. Для этого ответа, вот ваниль пример:

appcache.js:

window.applicationCache.addEventListener('updateready', function(e) { 
    if (window.applicationCache.status == window.applicationCache.UPDATEREADY) { 
     // Browser downloaded a new app cache. 
     // Swap it in and reload the page to get the latest hotness. 
     window.applicationCache.swapCache(); 
     if (confirm('A new version of the application is available. Would you like to load it?')) { 
      window.location.reload(); 
     } 
    } 
    else { 
     // Manifest didn't changed. Don't do anything. 
    } 
}, false); 

В качестве альтернативы, если AppCache не будет работать для вашей ситуации, более Гетто решением было бы создать простой API конечной точки который возвращает текущий идентификатор сборки или дату последнего развертывания. Ваше угловое приложение иногда попадает в эту конечную точку и сравнивает результат с его внутренней версией, а если отличается, перезагружается сама.

Или вы можете рассмотреть сценарий live-reload (example), но, будучи очень полезным в разработке, я не уверен, насколько хороша идея использовать live/in-place-reloading активы в производство.

+0

Вау! AppCache. Я думаю, что это может быть немного для того, что мне нужно ... особенно, поскольку я вижу, что IE9 не выглядит поддерживаемым, и Firefox, похоже, требует согласия пользователя. Мне действительно нравится идея решения «гетто» - проверка конечной точки API с заданным интервалом и вызов window.location.reload(), если это необходимо.На самом деле мне кажется приятным и простым ... хотя я уверен, что кто-то скажет мне, что я могу сделать то же самое так же легко с socket.io .... – Andrew

+0

yea; вы можете сделать это с помощью socket.io .. но это слишком много накладных расходов только для «обновления в реальном времени». Пинг сервера на тайм-аут кажется достаточным (и более дешевым с точки зрения ресурсов, вам не нужно беспокоиться о загрузке открытых соединений сокетов или беспокоиться о балансировке нагрузки при масштабировании ..) Если, конечно, ваше приложение уже использует socket.io. Тогда это имеет смысл. –

+0

Yep - Я думаю то же самое ... слишком много накладных расходов. Вероятно, мы добавим socket.io в ближайшие несколько месяцев, но я думаю, что будет идти с использованием подхода ping API до тех пор, пока мы на самом деле этого не сделаем. Спасибо за Ваш ответ! – Andrew

0
  1. Постарайтесь ограничить ваши js/файлы истечением в течение меньшего периодического периода, то есть: 1 день.
  2. Но в случае, если вы хотите что-то, что выдвижная и передать пользователю перезагрузить (Ctrl + f5) своего браузера, а затем просто сделать сценарий, всплывающее окно, что новости, если вы просто изменили некоторые из файлов, знак ip/session, которые просто перезагрузили/сказали перезагрузить, поэтому их не будет раздражать несколько всплывающих окон.
+0

Пункт 1 является справедливым. Я изменил время до истечения срока действия CDN для статических активов до 1 дня с 7 дней. – Andrew

1

Возможно, вы можете добавить хэш в свое имя файла кода клиента. например app-abcd23.js.
Таким образом, браузер перезагрузит файл, а не получит его из кеша. или вы можете просто добавить хэш в url.eg app.js?hash=abcd23, но некоторые браузеры все равно могут использовать кешированную версию.

Я знаю, что рельсы имеют активы-трубопровод для обработки, но я не знаком с MEAN stack. для этой цели должен быть пакет в npm.

И я не думаю, что действительно необходимо использовать socket.io, если вы хотите уведомить пользователя, что их код клиента устарел. вы можете определить свою версию как в файлах html meta tag, так и в js, если это несоответствие, покажите всплывающее окно и сообщите об этом пользователю.

+0

Спасибо! Это SPA, хотя ... поэтому я не уверен, что метатег html и js-версия файла будут работать. Понятно, что пользователь может оставить окно браузера открытым на неделю, вернуться и начать использовать приложение без перезагрузки, а метатег и версия файла js не будут изменены. Точка именования файлов является хорошей, но такая же проблема - исправляет кеш при перезагрузке, но не если пользователь не перезагружает. Правильно? – Andrew

+0

Да, добавить хеш в имя файла для кеша браузера и cdn. поэтому я думаю, что каждый день или один день делайте ajax-звонок, чтобы увидеть, есть ли там новая версия, а затем обновить страницу с помощью js, которая может работать для вас. socket.io все еще слишком много для этого. И если вы хотите добавить вещи в реальном времени в свое приложение, я предлагаю использовать firebase или parse вместо использования socket.io. – at15

+0

Большое спасибо за ваш ответ! – Andrew

0

Я столкнулся с той же проблемой в последнее время. Я исправил это, добавив номер сборки моего приложения в файлы js/css. Все мои теги сценария и стиля были включены в сценарий в общей включаемые файлы, так что было тривиальным, чтобы добавить «номер сборки» в конце пути JS/CSS файл, как этот

/foo/bar/main.js?123 

Это 123 является номер, который я отслеживаю в том же заголовочном файле. Я увеличиваю его, когда хочу, чтобы клиент принудительно загрузил все js-файлы приложения. Это дает мне контроль над загрузкой новых версий, но позволяет браузеру использовать кеш для каждого запроса после первого. Это до тех пор, пока я не нажму другое обновление, увеличив номер сборки.

Это также означает, что у меня может быть заголовок истечения кеша, сколько бы я ни захотел.

Смежные вопросы