我的目标是不重复onStompErrorCallback回调。
ps:我正在研究另一种解决方案,我认为它会起作用。
翻译:博士
目前的解决方案是onStopErrorCallback直接在 React Hook 中编写。
function LoginScreen() {
const dispatch = useDispatch();
const onStopErrorCallback = (receipt: IFrame) => {
dispatch(doSomething());
}
}
但是这会带来问题,因为有两种情况:
当用户登录时,例如在一个被调用的组件中,
LoginScreen有一个被调用的方法login。该login的方法做两件事情:- 向 API 发送 POST 请求并获取令牌作为响应。
- 做
WebSocket handshake,然后StompCommand.CONNECT,StompCommand.SUBSCRIBE。
如果用户按下
login button,它将调用该方法。当用户打开应用程序时:
- 该
App组件将发送一个 GET 请求来验证令牌。如果令牌未过期,它将执行WebSocket handshake, 然后StompCommand.CONNECT, 和StompCommand.SUBSCRIBE。
- 该
问题是:
- 每个场景都需要访问
onStompErrorCallback,我不能在不复制代码的情况下将它放在任何地方,increase code smell因为它取决于dispatch(doSomething()).
我试过的:
我试图存储
new Client(stompConfig: StompConfig)到 redux。Redux 不能存储
onStopErrorCallback: () => void,或者new Client(stompConfig: StompConfig). 它会抛出一个错误。我尝试使用自定义钩子,例如
useStompClient(X_Auth_Token: string).每次组件或屏幕调用时
useStompClient(X_Auth_Token: string),它都会创建新的stompClient而不是使用现有的stompClient。我尝试使用 thunk
onStompErrorCallback在
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;
解决方案?创建第二层身份验证:
- 应用程序
- 认证层
- 网络套接字层
打打!登录并打开应用程序场景,它会按预期工作。