微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在@stomp/stomp-js 库的 onStompErrorCallback 内部使用 dispatch? TL:DR编辑

如何解决如何在@stomp/stomp-js 库的 onStompErrorCallback 内部使用 dispatch? TL:DR编辑

我的目标是不重复 onStompErrorCallback 回调。

ps:我正在研究另一种解决方案,我认为它会奏效。

TL:DR

目前的解决方案是在 React Hook 中直接编写 onStopErrorCallback

function LoginScreen() {
  const dispatch = usedispatch();

  const onStopErrorCallback = (receipt: IFrame) => {
    dispatch(doSomething());   
  }
}

然而这会带来问题,因为有两种情况:

  1. 用户登录时,例如在名为 LoginScreen 的组件中,有一个名为 login方法login方法做两件事:

    1. 向 API 发送 POST 请求并获取令牌作为响应。
    2. 先做WebSocket handshake,然后是StompCommand.CONNECTStompCommand.SUBSCRIBE

    如果用户按下 login button,它将调用方法

  2. 用户打开应用时:

    1. App 组件将发送一个 GET 请求来验证令牌。如果令牌没有过期,它会执行 WebSocket handshake,然后是 StompCommand.CONNECT,然后是 StompCommand.SUBSCRIBE

问题是:

  1. 每个场景都需要访问 onStompErrorCallback,我不能在不复制代码 increase code smell 的情况下将它放在任何地方,因为它取决于 dispatch(doSomething())

我尝试过的:

  1. 我尝试将 new Client(stompConfig: StompConfig) 存储到 redux

    Redux 无法存储 onStopErrorCallback: () => voidnew Client(stompConfig: StompConfig)。它会抛出错误

  2. 我尝试使用自定义钩子,例如 useStompClient(X_Auth_Token: string)

    每次组件或屏幕调用 useStompClient(X_Auth_Token: string) 时,它都会创建新的 stompClient,而不是使用现有的 stompClient

  3. 我尝试对 onStompErrorCallback

    使用 thunk

    stompClient 无法连接/订阅/发送消息。

    const onStompErrorCallback = (receipt: IFrame): AppThunk => dispatch => {
      dispatch(doSomething());
    }
    

编辑

这是我可以用自定义钩子做的最好的事情。这不是一个解决方案,useStompClient 将 stompClient 视为 null,尽管它不是,然后重新渲染(这次它看到 stompClient 为非 null)。

let stompClient: Client | null = null;

function useStompClient(X_Auth_Token: string) {
  const dispatch = usedispatch();

  if (stompClient === null && X_Auth_Token !== '') {
    const onConnectCallback = () => {
      console.log('STOMP: connecting');
      stompClient?.subscribe('/user/queue/messages',(message) => {
        const payload = JSON.parse(message.body);
        console.log(payload);
      });
    };

    const onStompErrorCallback = (receipt: IFrame) => {
      if (receipt.headers.message.endsWith('Access is denied')) {
        stompClient?.deactivate();
        dispatch(eraseCredentials());
      }
    };

    const stompConfig: StompConfig = {
      brokerURL: `${environment.wsBaseURL}/chat`,forceBinaryWSFrames: true,appendMissingNULLonIncoming: true,connectHeaders: {
        'X-Auth-Token': X_Auth_Token,},onConnect: onConnectCallback,onStompError: onStompErrorCallback,};

    stompClient = new Client(stompConfig);
  }

  return stompClient;
}

export default useStompClient;

解决方案?创建第二层身份验证:

  1. 应用
  2. 身份验证层
  3. WebSocketLayer

他打!登录并打开应用场景,它会按预期工作。

解决方法

解决方案?创建第二层身份验证:

  1. 应用:这是 ReduxNavigationContainer 所在的位置。
  2. AuthenticationLayer:这是 Stack.Navigator 所在的位置,例如
return (
  <Stack.Navigator>
    authenticated ? <Stack.Screen component={LoginScreen} /> : <Stack.Screen component={HomeScreen} />
  </Stack.Navigator>
)
  1. WebSocketLayer
The WebSocketLayer requirements:
1. The `authenticated` is set to true,meaning the app already have the token and ready to be used.
2. Create the `onStompErrorCallback`,etc.
3. Put the stompClient and create a custom setters somewhere outside the React function.
4. Use React.useEffect() to set the stompClient.

他打!登录并打开应用场景,它会按预期工作。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?