Reputation: 31
how can i setup websocket between react native and spring boot. this works if you use html+js, but it doesn't work with react native.
spring config class
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket").setAllowedOriginPatterns("*").withSockJS();
}
}
spring controller class
@Controller
@CrossOrigin("*")
public class WebSocketController {
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
System.out.println(message.getName());
return new Greeting("Hello WORK, " + message.getName() + "!");
}
}
react native component
import React, { useEffect, useState } from 'react';
import { View, TextInput, Button } from 'react-native';
import SockJS from 'sockjs-client';
import { Stomp } from '@stomp/stompjs';
import { TextEncoder } from 'text-encoding';
global.TextEncoder = TextEncoder;
const Test = () => {
const [message, setMessage] = useState('');
const [stompClient, setStompClient] = useState(null);
useEffect(() => {
const socket = new SockJS('http://192.168.1.234:8081/websocket');
const client = Stomp.over(socket);
const connectToWebSocket = () => {
client.connect({}, () => {
setStompClient(client);
client.subscribe('http://192.168.1.234:8081/topic/greetings', (message) => {
console.log('Received message:', message.body);
});
});
};
connectToWebSocket();
return () => {
if (stompClient) {
stompClient.disconnect();
}
};
}, []);
const sendMessage = () => {
if (stompClient) {
stompClient.send('http://192.168.1.234:8081/app/hello', {}, message);
setMessage('');
}
};
export default Test;
I tried several libraries, but nothing worked for me (
I need to try to set up a connection using the topic
how can i setup websocket between react native and spring boot. this works if you use html+js, but it doesn't work with react native.
Upvotes: 3
Views: 800
Reputation: 35
I successfully implemented a real-time chat application using Spring Boot, WebSocket, SockJS, and Stomp. My setup works seamlessly with both Angular and React Native Mobile App. I want to share the configuration and code to help others who might encounter similar requirements. Here’s my working setup:
Backend Configuration: Dependencies:
implementation 'org.springframework.boot:spring-boot-starter-websocket'
implementation 'org.webjars:sockjs-client:1.0.2'
implementation 'org.webjars:stomp-websocket:2.3.3'
WebSocket Configuration:
@Configuration
@EnableWebSocketMessageBroker
@Order(Ordered.HIGHEST_PRECEDENCE + 99)
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws")
.setAllowedOrigins("http://192.168.0.184:4201","http://localhost:4200")
.withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry brokerRegistry) {
brokerRegistry.setApplicationDestinationPrefixes("/app");
brokerRegistry.enableSimpleBroker("/topic", "/queue", "/user");
brokerRegistry.setUserDestinationPrefix("/user");
}
}
Controller for Handling Messages:
@RequiredArgsConstructor
@RestController
public class RealTimeChat {
private final SimpMessagingTemplate messagingTemplate;
private final ServiceMessage serviceMessage;
private final WebSocketSessionRegistry sessionRegistry;
private static final Logger LOGGER = LoggerFactory.getLogger(RealTimeChat.class);
@MessageMapping("/chat.sendPrivate")
public void sendPrivateMessage(@Payload DtoMessage chatMessage) {
try {
String recipientUser = chatMessage.getUser() + "";
LOGGER.info("Sending message to: {}", recipientUser);
messagingTemplate.convertAndSendToUser(recipientUser, "/queue/private", chatMessage);
} catch (Exception e) {
e.printStackTrace();
}
}
@MessageMapping("/chat.register")
public DtoMessage register(@Payload DtoMessage chatMessage, SimpMessageHeaderAccessor headerAccessor) {
try {
String sessionId = headerAccessor.getSessionId();
headerAccessor.getSessionAttributes().put(chatMessage.getUser() + "", sessionId);
sessionRegistry.registerSession(chatMessage.getUser(), sessionId);
return chatMessage;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
}
Frontend Configuration: React Hook for Connecting to WebSocket:
useEffect(() => {
const socket = new SockJS(wsUrl);
const client = new Client({
webSocketFactory: () => socket,
debug: str => console.warn(str),
onConnect: () => {
console.log('Connected to WebSocket');
client.subscribe('/chat.register', message => {
const receivedMessage = JSON.parse(message.body);
console.log('[WebSocket] Received message:', receivedMessage);
});
},
onDisconnect: () => {
console.log('Disconnected from WebSocket');
},
onStompError: error => {
console.error('Stomp error:', error);
},
});
client.activate();
setStompClient(client);
return () => {
client.deactivate();
};
}, [userId, tenantId]);
Sending a Private Message:
const sendMessage = () => {
const message = {
userIdSend: 'ed477317-5fe8-4841-a13d-e45e01eb94be',
userIdTo: '1',
content: 'Testing message...',
type: true,
};
stompClient.publish({
destination: '/app/chat.sendPrivate',
body: JSON.stringify(message),
});
setNewMessage('');
};
Upvotes: 0