Веб-сокеты в Sapper - PullRequest
       122

Веб-сокеты в Sapper

0 голосов
/ 07 августа 2020

У меня есть читаемый магазин в Svelte, который выглядит так:

const state = {};
export const channels = readable(state, set => {
        let st = state;
        let socket = new WebSocket("ws://127.0.0.1:5999");
    
        socket.onmessage = function (event) {
          var datastr = event.data.split(':');
          st[datastr[0]].value = datastr[1];
          st[datastr[0]].timestamp = Date.now();
                    set(st)
        };
          return () => {
                    socket.close()
                }
    
});

Когда я импортирую его в свое приложение Svelte, работает. Но если я поставлю этот App.svelte в качестве моего index.svelte, работающего на Sapper, он сначала не будет работать. В нем говорится, что ошибка 500 веб-сокет не определена. Как только я перезагружаю страницу в браузере, она начинает работать ... Я пытаюсь разобрать функцию, которая вместо этого создает хранилище:

export const getChannel = () => {
 // here my store
return {...store}
}

, а затем создаю хранилище внутри onMount () следующим образом:

onMount( ()=> {
    const channel = getChannel();
});

Но, похоже, это не помогает ... Что я упускаю? Примечание: если просто заменить хранилище простым записываемым и создать веб-сокет onMount (), он будет работать без каких-либо проблем. Я просто хотел, чтобы все сообщения внутри магазина были доступны для чтения ...

1 Ответ

0 голосов
/ 12 августа 2020

В Sapper код в компонентах (или импортированный в компоненты) выполняется в Node во время рендеринга на стороне сервера, если он не помещен внутрь onMount (который не выполняется на сервере, потому что не происходит «монтирования») или блок if (process.browser) {...} или что-то подобное.

Сюда входят такие вещи, как ссылки на $channels, вызывающие вызов channels.subscribe(...) во время инициализации.

Поскольку в Node нет WebSocket global , создание этой подписки не удастся. Самым простым решением, вероятно, является простая проверка функций:

const state = {};
export const channels = readable(state, (set) => {
  if (typeof WebSocket === 'undefined') return;

  let st = state;
  let socket = new WebSocket("ws://127.0.0.1:5999");

  socket.onmessage = function (event) {
    var datastr = event.data.split(":");
    st[datastr[0]].value = datastr[1];
    st[datastr[0]].timestamp = Date.now();
    set(st);
  };
  return () => {
    socket.close();
  };
});
...