React Native中使用@stomp/stompjs建立WebSocket连接失败问题求助
Hey there, let's break down why your STOMP onConnect callback isn't firing. From your logs, we can see the WebSocket opens successfully and sends the CONNECT frame—but the server never sends back a CONNECTED frame, which is why onConnect never triggers. Here are actionable steps to fix this:
1. Verify Your WebSocket Endpoint
Double-check that your brokerURL (ws://203xxxxxxxx/xxx/connectSocket) is 100% correct:
- Typos in the path or domain are a common culprit. Confirm with your backend team that this endpoint is designed to handle STOMP connections (some servers use paths like
/stompor/wsinstead). - For React Native, if you're testing with a non-HTTPS endpoint:
- iOS: Add an exception to
Info.plistunderNSAppTransportSecurityto allow cleartext traffic. - Android: Set
android:usesCleartextTraffic="true"in yourAndroidManifest.xml.
- iOS: Add an exception to
2. Check Required Connection Headers
Many STOMP servers require authentication (tokens, username/password) in connectHeaders. If your server expects this, add the necessary credentials:
const stompConfig = { // ... other configs connectHeaders: { Authorization: `Bearer ${yourAuthToken}`, // If using JWT // OR username: "your-username", password: "your-password" }, };
Missing auth will often cause the server to silently drop the connection without sending a CONNECTED frame.
3. Debug Heartbeat Configuration
Your current heartbeat setting (10000,10000) might not align with what your server expects. Try adjusting or temporarily disabling heartbeats to rule this out:
const stompConfig = { // ... other configs heartbeatIncoming: 0, heartbeatOutgoing: 0, };
If this fixes the issue, work with your backend team to match the server's heartbeat requirements.
4. Fix Client Instance Scope
In React components, using a global stompClient can lead to unexpected behavior (like the instance being reset on re-renders). Use useRef to preserve the client instance across renders:
import { useRef, useEffect } from 'react'; import { Client } from '@stomp/stompjs'; // Inside your component const stompClientRef = useRef(null); useEffect(() => { const userId = "your-valid-user-id"; // Ensure this is defined! const stompConfig = { connectHeaders: {}, brokerURL: "ws://203xxxxxxxx/xxx/connectSocket", debug: (str) => console.log('STOMP: ' + str), reconnectDelay: 200, onConnect: (frame) => { console.log("connected"); const subscription = stompClientRef.current.subscribe(`/topic/public/${userId}`, (message) => { console.log(JSON.parse(message.body)); }); }, onStompError: (frame) => { console.log('STOMP Error:', frame.headers, frame.body); }, onWebSocketError: (error) => { console.error('WebSocket Error:', error); }, }; stompClientRef.current = new Client(stompConfig); stompClientRef.current.activate(); // Cleanup on unmount return () => { if (stompClientRef.current) { stompClientRef.current.deactivate(); } }; }, []);
This ensures your client instance stays intact and doesn't get reinitialized accidentally.
5. Test the Endpoint with a Tool
Use a tool like wscat to test if the server responds to STOMP connections outside of your app:
- Install wscat:
npm install -g wscat - Connect to your endpoint:
wscat -c ws://203xxxxxxxx/xxx/connectSocket - Send a STOMP CONNECT frame (note the trailing null character, sent with
Ctrl+@):
CONNECT accept-version:1.0,1.1,1.2 heart-beat:10000,10000 ^@
If the server doesn't send back a CONNECTED frame here, the issue is on the backend side—ask your team to check if the STOMP broker is running and configured correctly.
6. Ensure userId is Defined
Double-check that userId has a valid value when you try to subscribe. While this won't prevent onConnect from firing, it will break your subscription once you do connect, so it's worth verifying early.
内容的提问来源于stack exchange,提问作者Manjunath P

