为什么收不到websocket消息

问题描述 投票:0回答:1

我正在尝试制作一个组件来呈现订单。我在 React 上使用 MVVN 架构。与后端的连接基于websocket连接。当我测试后端 webscoket 连接时,我能够得到响应。但在我的前端,我只看到发送的消息,但没有回复。我认为我处理 useEffect 的方式是错误的。但我不知道在哪里。

这是前端代码:

import { useCallback, useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import useWebSocket, { ReadyState } from 'react-use-websocket'

import { UseCase } from '@/domain/model/types'
import { Epc, Order } from '@/domain/model/OrderTagging'
import { PrinterPoint, Terminal } from '@/domain/model/PrinterPoint'

import { ROUTES } from '@/utils/common/constant'
import { toaster } from '@/utils/common/toaster'
import { StorageKeys } from '@/utils/common/constant/storage'

import useStoreDataInLocalStorage from '@/hooks/useStoreDataInLocalStorage'

import { closeCodeMessages, WebSocketCloseCode } from './webSocketCloseCodes'

import { FormDataSchema } from '@/presenter/components/OrderForm/view-models/types'

type Dependencies = {
  readonly getOrderUseCase: UseCase<Order>
}

export type UseOrderViewModelResponse = {
  order: Order | null
  queue: Epc[] | null
  isLoading: boolean
  sendMessageOnSubmit: (formData: FormDataSchema) => void
}

export const useOrderViewModel = ({ getOrderUseCase }: Dependencies): UseOrderViewModelResponse => {
  const [order, setOrder] = useState<Order | null>(null)
  const [queue] = useState<Epc[] | null>(null)
  const [socketUrl, setSocketUrl] = useState<string | null>(null)
  const [isLoading, setIsLoading] = useState(true)
  const navigate = useNavigate()

  const { value: locality } = useStoreDataInLocalStorage<PrinterPoint>(StorageKeys.User.Locality)
  const { value: terminal } = useStoreDataInLocalStorage<Terminal>(StorageKeys.User.Terminal)

  const { sendJsonMessage, lastJsonMessage, readyState } = useWebSocket(socketUrl, {
    onOpen: () => {
      // eslint-disable-next-line no-console
      console.log('Open connection')
    },
    onMessage: (evt) => {
      // eslint-disable-next-line no-console
      console.log('Message received:', evt.data)
    },
    onClose: () => {
      // eslint-disable-next-line no-console
      console.log('Close connection')
    },
    onError: () => {
      // eslint-disable-next-line no-console
      console.log('Close onError')
    },
    shouldReconnect: (evt) => {
      try {
        const { message, isError } = handleWebSocketCloseCode(evt.code as WebSocketCloseCode)
        toaster('error', message)
        return isError
      } catch (e) {
        // eslint-disable-next-line no-console
        console.log(e)
        return false
      }
    },
    reconnectInterval: 1500,
    reconnectAttempts: 3
  })

  function handleWebSocketCloseCode(code: WebSocketCloseCode) {
    const message = closeCodeMessages[code] || `Código de fechamento desconhecido: ${code}`
    const isError = code !== 1000

    return { message, isError }
  }

  const sendMessageOnSubmit = (formData: FormDataSchema) => {
    sendJsonMessage({
      action: 'start_print',
      data: {
        storeNumber: order?.storeNumber,
        ean: formData.product,
        quantity: formData.quantity,
        expiryDate: formData.expiryDate,
        productSession: formData.product
      }
    })
  }

  const getOrderData = useCallback(async () => {
    try {
      setIsLoading(true)
      sendJsonMessage({
        action: 'open_order',
        data: {
          boxBarcode: '00002919802331',
          bureauIdentifier: 'cd_x',
          storeNumber: '21955',
          owner: 'user1',
          terminalIdentifier: 'Bancada 01'
        }
      })
    } catch (error) {
      toaster('error', 'Erro ao carregar os dados do pedido. Por favor, tente novamente.')
      navigate(`/${ROUTES.TABS}`)
    } finally {
      setIsLoading(false)
    }
  }, [])

  useEffect(() => {
    const controller = new AbortController()

    if (locality?.identifier && terminal?.name) {
      setSocketUrl(`${import.meta.env.VITE_SOCKET_CONNECT}/${locality.identifier}/${terminal.name}`)
    }

    ;(async () => await getOrderData())()

    return () => {
      controller.abort()
    }
  }, [])

  return { order, queue, isLoading, sendMessageOnSubmit }
}

这是控制台视图: enter image description here

javascript reactjs typescript websocket frontend
1个回答
0
投票

要解决 React 组件发送 WebSocket 消息但未收到响应的问题,请仔细检查 WebSocket 连接的 useEffect 处理: WebSocket 初始化:在 useEffect 中,确保使用正确的 URL 初始化 WebSocket,并且正确处理 onopen、onmessage、onerror 和 onclose 等所有事件。 onMessage 处理:确保您在 onmessage 事件中正确接收和处理消息。通常,后端响应是JSON格式的,因此解析event.data 清理WebSocket连接:确保在清理函数中正确关闭WebSocket,以防止内存泄漏。 检查后端响应:确保后端正确发送对 WebSocket 消息的响应。

© www.soinside.com 2019 - 2024. All rights reserved.