我是 React Native 的新手,我正在尝试编写一个小应用程序,该应用程序连接到由 Rails ActionCable 提供支持的 Websocket,发送一条消息,然后当我单击“断开连接”时,它会关闭连接并取消订阅频道。
这是我在 React Native 端的代码:
import React, { useState, useEffect, useCallback } from 'react';
import { View, Text } from 'react-native';
import { Button } from 'react-native-paper';
import { ActionCable, Cable } from '@kesha-antonov/react-native-action-cable';
import UUID from 'react-native-uuid';
const actionCable = ActionCable.createConsumer('wss://blabla.ngrok-free.app/cable');
const cable = new Cable({})
const App: React.FC = () => {
//const actionCable = ActionCable.createConsumer('wss://blabla.ngrok-free.app/cable');
//const cable = new Cable({})
// const channel = cable.setChannel(
// `wire_channel_${identifier}`, // channel name to which we will pass data from Rails app with `stream_from`
// actionCable.subscriptions.create({
// channel: 'WireChannel', // from Rails app app/channels/chat_channel.rb
// })
// )
const [isWebsocketConnected, setIsWebsocketConnected] = useState(false);
const [dchannel, setDchannel] = useState();
const identifier = UUID.v4();
console.log(identifier);
const onNewMessage = useCallback(message => {
}, [])
const handleReceived = useCallback(({ type, message }) => {
console.log(type);
console.log(message);
console.log("triggered")
}, [])
const handleConnected = useCallback(() => {
setDchannel(cable.setChannel(
`wire_channel_${identifier}`, // channel name to which we will pass data from Rails app with `stream_from`
actionCable.subscriptions.create({
channel: 'WireChannel', // from Rails app app/channels/chat_channel.rb
})
))
setIsWebsocketConnected(true)
}, [])
const handleDisconnected = useCallback(() => {
removeChannel()
setIsWebsocketConnected(false)
}, [])
const handleSendMessage = useCallback(() => {
const channelName = getChannelName(identifier)
const channel = cable.channel(channelName)
dchannel.perform('speak', { message: 'Hey', identifier: identifier })
})
const getChannelName = (identifier) => {
return `wire_channel_${identifier}`
};
const removeChannel = useCallback(() => {
const channelName = getChannelName(identifier)
console.log("getChannelName: "+channelName);
const channel = cable.channel(channelName)
console.log(channel);
if (!channel)
return
channel
.removeListener( 'received', handleReceived )
.removeListener( 'connected', handleConnected )
.removeListener( 'disconnected', handleDisconnected )
channel.unsubscribe()
console.log(cable.channels)
delete( cable.channels[channelName] )
console.log(cable.channels)
}, [])
useEffect(() => {
// channel.on('received', handleReceived);
// channel.on('connected', handleConnected);
// channel.on('disconnected', handleDisconnected);
return () => {
if(dchannel){
dchannel.unsubscribe();
}
};
}, []);
return (
<View style={{ flex: 1 }}>
<View style={{ padding: 20, backgroundColor: '#f0f0f0', alignItems: 'center' }}>
<Text style={{ fontSize: 24 }}>Your Logo Here</Text>
</View>
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Button
mode="contained"
onPress={handleConnected}
color="#00C853" // Green color for "Connect" button
disabled={isWebsocketConnected}
>
Connect WebSocket
</Button>
<Button
mode="contained"
onPress={handleDisconnected}
color="#FF1744" // Red color for "Disconnect" button
disabled={!isWebsocketConnected}
>
Disconnect WebSocket
</Button>
<Button
mode="contained"
onPress={handleSendMessage}
disabled={!isWebsocketConnected}
>
Send Message
</Button>
<Text>
WebSocket Status: {isWebsocketConnected ? 'Connected' : 'Disconnected'}
</Text>
{/*<Text>Counter: {counter}</Text>
<View style={{ marginTop: 20 }}>
<Text>Messages from Server:</Text>
{messages.map((message, index) => (
<Text key={index}>{message}</Text>
))}
</View>*/}
</View>
</View>
);
};
export default App;
我遇到的问题是,当应用程序加载时,我看到在服务器端创建了很多订阅,当我单击“发送消息”时,服务器广播多条消息(每个创建的订阅一条消息)。我只想建立 1 个订阅,并且应该仅在我单击“连接 Websocket”按钮时建立。
如何在上面的代码中实现这一点。我已经尝试过多种方法了。
请删除代码中的 usecallback 挂钩并检查输出。 usecallback 并不适用于每个函数。请检查
有效使用 usecallback 挂钩。