Angular7: Сервисный работник не работает должным образом - PullRequest
0 голосов
/ 03 января 2019

У меня есть работник службы слежения, и я кэшировал звуки (файлы mp3), чтобы их можно было воспроизводить в автономном режиме. Вот это ngsw-config-json:

{
  "index": "/index.html",
  "assetGroups": [{
    "name": "app",
    "installMode": "prefetch",
    "resources": {
      "files": [
        "/favicon.ico",
        "/index.html",
        "/*.css",
        "/*.js",
        "/*.svg",
        "/*.eot",
        "/*.woff",
        "/*.woff2",
        "/*.tff"
      ]
    }
  }, {
    "name": "assets",
    "installMode": "prefetch",
    "updateMode": "prefetch",
    "resources": {
      "files": [
        "/assets/sounds/character1/**",
        "/assets/sounds/character2/**"
      ]
    }
  }]
}

В моем веб-приложении звуки звучат так:

let audioLink = `/assets/sounds/${character}/${soundURL}`;
let player = new Audio(audioLink);
player.play()

Сайт работает в автономном режиме. Файлы HTML, CSS, JS, JSON кэшируются. Но звуки не воспроизводятся (когда я пытаюсь играть, выдает ошибку, которую я показал выше).

В Инструментах разработчика Chrome> Приложение > Кэш я вижу, что там есть несколько звуков (пути), но не все. Но никто из них не работает в автономном режиме.

Иногда возникают такие ошибки:

  • GET "path/to/file" net::ERR_ABORTED 504 (Gateway Timeout)
  • Uncaught (in promise) DOMException
  • Failed to load resource: net::ERR_INTERNET_DISCONNECTED

Иногда также говорится, что с manifest.json есть проблема, но в этом нет ничего плохого, поскольку он обнаруживается в разделе манифеста инструментов разработчика при подключении к сети.

Есть ли какое-нибудь решение этой проблемы? Это не ошибка Chrome, потому что я вижу такое же поведение в Safari и Firefox. Я знаю, что есть ошибка в новой версии Chrome, и из-за этой ошибки favicon.ico не отображается в автономном режиме

Не уверен, поможет ли это, но здесь - ссылка на размещенное веб-приложение. Если вы видите вкладку «Сеть» в Chrome Developer Tools, вы можете видеть, что mp3-файлы «загружаются», но не воспроизводятся в автономном режиме.

После создания сайта для производства (ng build --prod --base-href="/") я посмотрел на ngsw.json, и вот что я увидел (некоторые строки удалены):

{
  "name": "assets",
  "installMode": "prefetch",
  "updateMode": "prefetch",
  "urls": [
    "/assets/sounds/character1/sound one.mp3",
    "/assets/sounds/character1/sound two.mp3",
    "/assets/sounds/character2/sound three.mp3"
    "/assets/sounds/character2/sound four.mp3"
  ],
  "patterns": []
}

Здесь - полное сгенерированное ngsw.json. Все было настроено на предварительное кэширование, а не на кеширование.

И все эти URL-адреса активов также находятся в объекте "hashTable". Я также вижу, что они загружаются в инструменты разработчика Chrome (инструменты разработчика> сеть), но некоторые из них я вижу только в разделе кеша приложений (возможно, первые 20-30 из 150).

Что я здесь не так делаю? Может ли это быть ошибкой Angular 7? Я видел различные другие вопросы StackOverflow и Reddit об аналогичной проблеме.

Что-то, что я пытался изменить,

let audioLink = `/assets/sounds/${character}/${soundURL}`;

до

let audioLink = `assets/sounds/${character}/${soundURL}`;

(убрал косую черту в начале), но это не имело значения.

Я полностью уверен, что все пути к звуковым файлам верны, потому что при работе сайта в сети абсолютно нет ошибок.

Помимо вышесказанного, я попытался вручную изменить все URL и вставить %20 там, где должен был быть пробел. Например, изменив "/assets/sounds/character1/sound one.mp3" на "/assets/sounds/character1/sound%20one.mp3", но это тоже не сработало.

Одна вещь, которую я заметил, это то, что если вы заходите на веб-сайт в первый раз и ждете загрузки всех звуков, а затем через нематериал, закройте ваше интернет-соединение и опробуйте сайт, все звуки будут работать. Но только на некоторое время, обычно около 10-15 минут, они перестают работать. Я тестировал на Chrome, Chrome Android, Firefox, Safari и IOS Safari.

РЕДАКТИРОВАТЬ: Как кто-то предложил, я попытался изменить

{
  "name": "assets",
  "installMode": "prefetch",
  "updateMode": "prefetch",
  "urls": [
    "/assets/sounds/character1/sound one.mp3",
    "/assets/sounds/character1/sound two.mp3",
    "/assets/sounds/character2/sound three.mp3"
    "/assets/sounds/character2/sound four.mp3"
  ],
  "patterns": []
}

до

{
  "name": "assets",
  "installMode": "prefetch",
  "updateMode": "prefetch",
  "urls": [
    "/assets/sounds/**"
  ],
  "patterns": []
}

но сохраняется та же проблема: звуки кэшируются в автономном режиме, возможно, в течение 10-15 минут, после чего они не воспроизводятся в автономном режиме. Я смог проверить это только в Chrome и Chrome Android.

Ответы [ 2 ]

0 голосов
/ 06 января 2019

Я нашел ответ на свой вопрос с помощью @ codeninja.

Во-первых, audioLink должен быть прямой ссылкой на звук.Я размещаю сайт на Github, поэтому ссылка выглядит примерно так:

let url = `sounds/path_to_sound.mp3`
let audioLink = `https://raw.githubusercontent.com/username/repo_name/master/assets/sounds/${url}`;

Во-вторых, мы не можем просто использовать метод sound.play() с Audio(), мы должны получить аудио, используя HttpClient.Я не уверен, почему именно, но codeninja предположил, что способ кэширования файлов ngsw несовместим с классом Audio.Я не уверен, что это правда, но я обнаружил, что в автономном режиме мне пришлось использовать HttpClient, чтобы получить аудиоблок (показано ниже).Если нет, вы получите ошибку response not Ok.Даже если бы я дал прямую ссылку https://raw.githubusercontent.com/username/repo_name/master/assets/sounds/direct.mp3, она выдала бы ту же ошибку.

В целом код выглядит так:

Сначала есть функция getSound():

getSound(url) {
  return this.http.get(url, {responseType: 'blob'});
}

Затем в другой функции (playSound(url)) мы имеем это:

playSound(url) {
  let audioLink = `https://raw.githubusercontent.com/username/repo_name/master/assets/sounds/${url}`;

  this.getSound(audioLink)
    .subscribe(data => {
      console.log(data);
      // data is an audio blob
      let url = URL.createObjectURL(data);

      let sound = document.createElement('audio');
      sound.src = url;
      sound.play();
    })
}

Кроме того, мне также пришлось изменить ngsw-config.json.Я изменил только часть «активов», поэтому покажу, что:

{
  "name": "assets",
  "installMode": "lazy",
  "updateMode": "prefetch",
  "resources": {
    "files": [
    ],
    "urls": [
       "https://raw.githubusercontent.com/username/repo_name/master/assets/sounds/**"
    ]
  }
}

Мне также не удалось заставить его работать с «предварительной выборкой».Хотя кэшированные звуки теперь воспроизводятся в автономном режиме, они будут воспроизводиться только в том случае, если они воспроизводились ранее, поскольку для него установлено значение «lazy».

Я тестировал это решение на Chrome, Chrome Android и Firefox, и этоработает нормально.

0 голосов
/ 04 января 2019

Я попытался сделать демо, чтобы изолировать ошибку, и, кажется, работает.Заметил какой-то странный URL в кэше приложения: Imgur

Не уверен, что это является причиной проблемы.Вы упомянули, что звук работает после того, как вы отключили устройство, я думаю, это кеширование в браузере, а не в автономном кеше.Когда я пытался обновить страницу, звук никогда не работал.Я предполагаю, что конфигурация с ngsw или способ, которым ngsw кэширует файлы, несовместимы с классом Audio.

Вы можете проверить, работает ли он, передав большой объект в Audio, сначала загрузив его, используя @angular/common/http.Я думаю об этом, поскольку аудио файлы, кажется, находятся в другом каталоге кэша (см. Скриншот).Файлы css / js по какой-то причине хранятся по-разному, а аудиофайлы доступны (в автономном режиме) только для угловых.

Публикация в качестве ответа, поскольку для комментария это слишком долго

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...