WestAlex
WestAlex

Reputation: 31

React Native + Spring Boot + WebSocket

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

Answers (1)

Abrar Hussain
Abrar Hussain

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

Related Questions