Инструменты разработчика показывают множество запросов веб-сокетов к приложению чата, построенному с помощью реагирующего хука с функциональным компонентом. - PullRequest
0 голосов
/ 12 апреля 2020

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

Мои вопросы заключаются в том, что он генерирует новый запрос веб-сокета после клиента, который создается функциональным компонентом реакции с перехватом, отправка или получение сообщения другому клиенту, который также построен с помощью перехватчика реакции с функциональным компонентом. Я наблюдаю эту ситуацию на вкладке сети с фильтрацией websocket в инструментах разработчика браузера. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *} * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *} * * * * * * * * * * * * * *} * * * * * * * тогда во время 'i отправка и получение сообщений.

Вы можете прочитать код App.tsx из моего репозитория github . Ниже приведена выдержка из App.tsx для клиента типа реагирующего подключения:

export const App: React.FC<{}> = ({}) => {

  const [messages, setMessages] = useState<MessageType[]>([]);
  const testValue = { messages, setMessages };

  const ws = useRef(new WebSocket(URL));

  const renderCount = useRef(0);

  const submitMessage = (msg: MessageType) => {
    ws.current.send(JSON.stringify(msg));

    addMessage(msg);
  };

  const addMessage = (msg: MessageType) => {

    setMessages([...messages, msg]);

  };

  // websocket onmessage
  useEffect(() => {
    ws.current.onmessage = (msg) => {
      const message = JSON.parse(msg.data);
      message.isMe = false;

      addMessage(message);
    };

    console.log(`hello`);
  });

  // close websocket
  useEffect(() => {
    return () => {
      ws.current.close();
    };
  }, [ws]);


  return (
    <StylesProvider injectFirst>
      <div className="App" css={appStyle}>
        <AppBar position="sticky">
          {console.log(`renderCount: ${(renderCount.current += 1)}`)}
          {/* debug */}
          <Toolbar>
            <IconButton edge="start" color="inherit" aria-label="menu">
              <MenuIcon />
            </IconButton>
            <Typography variant="h6">聊天室</Typography>
          </Toolbar>
        </AppBar>

        <MessageHistory messages={messages} />
        <ChatInput submitFC={submitMessage} />
      </div>
    </StylesProvider>
  );
};

Ниже приведены снимки экрана двух локальных клиентов:
Получатель:
enter image description here enter image description here enter image description here enter image description here

Отправитель:
enter image description here enter image description here enter image description here

Хранилище другой клиентской версии, созданной компонентом класса реакции, находится в моего репозитория github .

Репозиторий сервера чата находится на моем github другом хранилище

1 Ответ

0 голосов
/ 12 апреля 2020

Я решаю эту проблему на основе этого решения из другого вопроса в stackoverflow, но я не знаю почему. Версия функционального компонента реагирования с крючком теперь может использовать только один веб-сокет в течение всего чата.

Код с пометкой "// изменен здесь", обозначенный ниже, является решением для App.tsx:

export const App: React.FC<{}> = ({}) => {

  const [messages, setMessages] = useState<MessageType[]>([]);
  const testValue = { messages, setMessages };

  // const ws = useRef(new WebSocket(URL));
  const ws = useRef<WebSocket | null>(null);  // changed here

  const renderCount = useRef(0);

  const submitMessage = (msg: MessageType) => {
    if (ws.current) {   // changed here
      ws.current.send(JSON.stringify(msg));
    }  // changed here

    addMessage(msg);
  };

  const addMessage = (msg: MessageType) => {

    setMessages((prev) => {   // changed here
      return [...prev, msg];  // changed here
    });                       // changed here
  };

  // websocket onmessage
  useEffect(() => {
    ws.current = new WebSocket(URL);  // changed here
    ws.current.onmessage = (msg: MessageEvent) => { // changed here
      const message = JSON.parse(msg.data);
      message.isMe = false;

      addMessage(message);
    };
  }, []);                     // changed here

  // close websocket
  useEffect(() => {
    return () => {
      if (ws.current) {       // changed here
        ws.current.close();
      }                       // changed here
    };
  }, [ws]);



  return (
    <StylesProvider injectFirst>
      <div className="App" css={appStyle}>
        <AppBar position="sticky">
          {console.log(`renderCount: ${(renderCount.current += 1)}`)}
          {/* debug */}
          <Toolbar>
            <IconButton edge="start" color="inherit" aria-label="menu">
              <MenuIcon />
            </IconButton>
            <Typography variant="h6">聊天室</Typography>
          </Toolbar>
        </AppBar>

        <MessageHistory messages={messages} />
        <ChatInput submitFC={submitMessage} />
      </div>
    </StylesProvider>
  );
};

Ниже приведены скриншоты. enter image description here enter image description here

...