Получайте сообщения в родительском и дочернем компоненте в SharedWorker

Я создал ShareWorker, используя этот скрипт.

// sharedWorker.js
importScripts('https://cdn.socket.io/4.3.1/socket.io.min.js');
let socket
let browserInstances = []
let counter = 0

onconnect = function(e) {
  const port = e.ports[0]
  browserInstances.push(port)


  if (!socket) {
    socket = io('socket-url');

    socket.on('message', (message) => {
      const msg = JSON.parse(message)
      browserInstances.map(instance => {
        instance.postMessage({type: msg.type, data: msg.data});
      });
    });
  }

}

я получаю два типа сообщений из сокета один — {тип: 'уведомление', данные: '12345'} а другой – {type: 'event', data: '12345'}

теперь есть два прослушивателя: один из них — мой основной компонент App.tsx, а другой — в моем дочернем компоненте.

это мой прослушиватель App.tsx

worker.port.onmessage = (event: any) => {
            console.info(event.data)
            if (event.data.type === 'notification') {
                console.info('Notification received:', event.data.data);
                // Handle notification logic here
              }
              // Do not consume the message, let it propagate to other components
              return true;
          }

и это мой прослушиватель childComponent.tsx

worker.port.onmessage = (event: any) => {
        console.info(event)
        if (event.data.type === 'event') {
          console.info('Event received:', event.data.data);
          // Handle event logic here
        }      
      }

И вот мой код WorkerContext.tsx, где я запускаю работника

// WorkerContext.ts

import React, { createContext, useEffect, useState, ReactNode } from 'react';


export const WorkerContext = createContext<any | undefined>(undefined);

interface WorkerProviderProps {
  children: ReactNode;
}


export const WorkerProvider: React.FC<WorkerProviderProps> = ({ children }) => {
  const [worker, setWorker] = useState<SharedWorker | null>(null);

  useEffect(() => {
    const sharedWorker = new SharedWorker('/sharedWorker.js');
    setWorker(sharedWorker);

    return () => {
      sharedWorker.port.close();
    };
  }, []);

  return (
    <WorkerContext.Provider value = {{ worker }}>
      {children}
    </WorkerContext.Provider>
  );
};

Проблема в том, что он получает сообщения только в компоненте App.tsx, сообщения не передаются в childComponent.tsx, но когда я удаляю прослушиватель App.tsx, они передаются в childComponent. Как я могу передать сообщение в приложение и дочерний компонент в зависимости от типа данных?

Указывает ли worker на тот же экземпляр SharedWorker, что подразумевается в ответе ниже, или вы создаете новый экземпляр для каждого компонента?

Kaiido 23.04.2024 09:39

он указывает на того же работника, что и я создал работника, используя ContextApi

Faizan Ahmad 23.04.2024 09:41

Однако вы на самом деле не показываете, как создали рабочего. Не могли бы вы отредактировать это в вашем вопросе?

Kaiido 23.04.2024 09:50

Я отредактировал свой вопрос и поместил туда код

Faizan Ahmad 23.04.2024 09:59
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

worker.port.onmessage = ___ присваивается свойству onmessage, перезаписывая любое значение, которое оно имело раньше (таким образом удаляя любой предыдущий прослушиватель событий, настроенный таким же образом). Вместо этого используйте worker.port.addEventListener("message", ___);, чтобы у вас было несколько слушателей события. См. документацию EventTargetдля addEventListener (MessagePort — подкласс EventTarget). Вам также необходимо вызвать start() на порту (установщик onmessage сделает это за вас).

когда я добавляю это worker.port.addEventListener("message", ___);, оно не принимает никаких сообщений

Faizan Ahmad 23.04.2024 09:48

@FaizanAhmad - Похоже, вы приняли ответ. Означает ли это, что ваш комментарий выше устарел?

T.J. Crowder 23.04.2024 11:44

Другие вопросы по теме