简体   繁体   中英

Flutter websockets + Spring Boot chat application

I'm trying to setup connection between Flutter and Spring boot as backend using websocket, but I came across many problems. I found in the Internet many tutorials even on StackOverflow but still I can't correctly build my chat application. I have been using this tutorial for backend: https://kiberstender.github.io/miscelaneous-spring-websocket-stomp-specific-user/

I just want to simple print the log on my backend service after incoming message, but I don't know what I'm doing wrong.

Flutter code:

try {
  StompClient stompClient = StompClient(
    config: StompConfig(
      url: "ws://10.0.2.2:8080/websocket-chat",
      onStompError: (StompFrame frame) {
        print(
            'A stomp error occurred in web socket connection :: ${frame.body}');
      },
      onWebSocketError: (dynamic frame) {
        print(
            'A Web socket error occurred in web socket connection :: ${frame.toString()}');
      },
      onDebugMessage: (dynamic frame) {
        print(
            'A debug error occurred in web socket connection :: ${frame.toString()}');
      },
      onConnect: (StompClient client, StompFrame connectFrame) {
        print(
            '${client.toString()} connected with the following frames ${connectFrame.body}');
        _stompClient = client;

        Map<String, String> asdf = {};
        var clientUnSubscribeFn = _stompClient.subscribe(
            destination: "ws://10.0.2.2:8080/user/queue/newMember",
            headers: asdf,
            callback: (frame) {
              // Received a frame for this subscription
              print("here" + frame.body);
            });
      },
    ),
  );
  stompClient.activate();
}

sendClientMessage(String msg) async {
Map<String, String> asdf = {};
var clientUnSubscribeFn = await _stompClient.subscribe(
    destination: "ws://10.0.2.2:8080/topic/newMember",
    headers: asdf,
    callback: (frame) {
      // Received a frame for this subscription
      print("here" + frame.body);
    });
_stompClient.send(
    destination: "ws://10.0.2.2:8080/app/register",
    body: "newUser\n",
    headers: asdf);
clientUnSubscribeFn = await _stompClient.subscribe(
    destination: "ws://10.0.2.2:8080/user/newUser/msg",
    headers: asdf,
    callback: (frame) {
      // Received a frame for this subscription
      print("here" + frame.body);
    });

}

Backend code:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
    config.enableSimpleBroker("/user", "/topic", "/queue");
    config.setApplicationDestinationPrefixes("/app");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint("/websocket-chat").setAllowedOrigins("*");
}

}

And the controller

    @MessageMapping("/register") // 3
@SendToUser("/queue/newMember")
public Set<String> registerUser(String webChatUsername) {
    logger.info(("reg"));
    if (!connectedUsers.contains(webChatUsername)) {
        connectedUsers.add(webChatUsername);
        simpMessagingTemplate.convertAndSend("/topic/newMember", webChatUsername); // 4
        logger.error(connectedUsers.toString());
        return connectedUsers;
    } else {
        return new HashSet<>();
    }
}

@MessageMapping("/unregister") // 5
@SendTo("/topic/disconnectedUser")
public String unregisterUser(String webChatUsername) {
    logger.info(("unreg"));
    connectedUsers.remove(webChatUsername);
    return webChatUsername;
}

@MessageMapping("/message") // 6
public void greeting(WebSocketMessage message) {
    logger.warn(("mes"));
    simpMessagingTemplate.convertAndSendToUser(message.toWhom, "/msg", message);

In your backend code try this:

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/websocket-chat").setAllowedOrigins("*");
registry.addEndpoint("/websocket-chat").setAllowedOrigins("*").withSockJS();
}

You don't need to supply the full URL again when subscribing/sending messages. So this:

var clientUnSubscribeFn = await _stompClient.subscribe(
    destination: "ws://10.0.2.2:8080/topic/newMember",
    headers: asdf,
    callback: (frame) {
      // Received a frame for this subscription
      print("here" + frame.body);
    });
_stompClient.send(
    destination: "ws://10.0.2.2:8080/app/register",
    body: "newUser\n",
    headers: asdf);

should be

var clientUnSubscribeFn = await _stompClient.subscribe(
    destination: "/topic/newMember",
    headers: asdf,
    callback: (frame) {
      // Received a frame for this subscription
      print("here" + frame.body);
    });
_stompClient.send(
    destination: "/app/register",
    body: "newUser\n",
    headers: asdf);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM