2
votes

Websocket Flutter avec backend Spring-boot

D'accord, Flutter a la recette WebSocket dans le livre de cuisine ( ici ). Et cela fonctionne très bien avec le serveur de test websocket.org.

Le fait est que je veux me connecter à mon propre serveur WebSocket. J'ai donc d'abord utilisé ce tutoriel de SpringBoot.

Essayer de faire une demande de l'application (j'utilise l'émulateur ici) au backend Spring Boot n'a pas fonctionné. J'ai alors commencé à bricoler et supprimé STOMP du backend de démarrage à ressort et je l'ai laissé avec un simple WebSocket passant des chaînes. Cela fonctionne lorsque vous utilisez un facteur ou même une page Web, mais cela ne fonctionne pas depuis l'application

L'état actuel est présent sur ce GitHub (les projets Spring Boot et Flutter): https://github.com/Flavsditz/websocket_sandbox

Quelqu'un at-il des conseils ici?

Je vous en suis reconnaissant!


0 commentaires

4 Réponses :


0
votes

Dans flutter-websocket_test/lib/message_page.dart vous avez ce qui suit à la ligne 6-7:

  final WebSocketChannel channel = IOWebSocketChannel.connect(
    Uri(scheme: "ws", host: "locahost", port: 8080, path: "/socket"),

Vous avez locahost au lieu de localhost , alors essayez de changer cela et voyez si cela fonctionne.


1 commentaires

Merci de l'avoir signalé, mais ce n'était en fait qu'une faute de frappe lorsque je préparais l'exemple.



2
votes

Après un peu de réflexion, j'ai trouvé le problème:

Le problème est que mon serveur spring-boot était sur localhost , mais le flutter (qui est également l'émulateur Android) a son propre service de bouclage. Donc, appeler localhost dans le programme Flutter fait référence à un autre endroit au lieu de celui que je voulais.

J'ai remplacé l' localhost par l'ip 10.0.2.2 qui est un alias du PC hôte qui est configuré pour aider au développement.

Pour plus d'informations, vérifiez cette réponse: ici

Bien sûr, si vous vouliez tester à partir d'un appareil réel, il faudrait publier le backend pour l'extérieur, donc cette réponse pourrait être meilleure: ici


0 commentaires

0
votes

Merci pour la solution, pour la note d'accompagnement si vous souhaitez tester dans un appareil réel que,

  1. L'appareil réel et le PC doivent tous deux être connectés au même réseau.
    (Dans mon cas, j'utilise le point d'accès de mon téléphone vers mon PC)

  2. Obtenez l'IP de votre PC avec cmd, tapez ipconfig pour obtenir l'IP.
    (Dans mon cas, son IPv4 Address. . . . . . . . . . . : 192.168.43.423 )

  3. Maintenant, collez votre IP au lieu de localhost
    Par exemple.

    IOWebSocketChannel.connect(Uri(scheme: "ws",host: "192.168.43.423",port: 8080,path: "/socket"))
    Merci


0 commentaires

0
votes

Pour ceux qui utilisent

stomp_dart_client: ^ 0.3.7

avec sockjs, n'oubliez pas de passer le jeton à l'en-tête

@Configuration
public class WebsocketSecurityConfiguration extends AbstractSecurityWebSocketMessageBrokerConfigurer {

    @Override
    protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
        messages
            .nullDestMatcher().authenticated()
            .simpDestMatchers("/topic/tracker").hasAuthority(AuthoritiesConstants.ADMIN)
           .simpSubscribeDestMatchers("/topic/**").authenticated()
            .simpDestMatchers("/topic/**").authenticated()
            // message types other than MESSAGE and SUBSCRIBE
            .simpTypeMatchers(SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE).denyAll()
            // catch all
            .anyMessage().denyAll();
    }

    /**
     * Disables CSRF for Websockets.
     */
    @Override
    protected boolean sameOriginDisabled() {
        return true;
    }
}


// spring security configs for http

@Override
    public void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
            .csrf()
            .disable()
            .addFilterBefore(corsFilter, UsernamePasswordAuthenticationFilter.class)
            .exceptionHandling()
                .authenticationEntryPoint(problemSupport)
                .accessDeniedHandler(problemSupport)
        .and()
            .headers()
            .contentSecurityPolicy("default-src 'self'; frame-src 'self' data:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://storage.googleapis.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:")
        .and()
            .referrerPolicy(ReferrerPolicyHeaderWriter.ReferrerPolicy.STRICT_ORIGIN_WHEN_CROSS_ORIGIN)
        .and()
            .featurePolicy("geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'none'; fullscreen 'self'; payment 'none'")
        .and()
            .frameOptions()
            .deny()
        .and()
            .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
            .authorizeRequests()
            .antMatchers("/api/**").authenticated()
            .antMatchers("/websocket/tracker").hasAnyAuthority(
                AuthoritiesConstants.ADMIN, AuthoritiesConstants.MANAGER, AuthoritiesConstants.STAFF,
                AuthoritiesConstants.CLIENT, AuthoritiesConstants.DRIVER
            )
            .antMatchers("/websocket/**").permitAll()
            .httpBasic()
        .and()
            .apply(securityConfigurerAdapter());
        // @formatter:on
    }

N'oubliez pas non plus de mettre à jour les configurations de sécurité Spring et les configurations de socket Web

initClient() async {
    try {

      if (_stompClient != null & _stompClient.connected) {
        return;
      }

      SharedPreferences _prefs = await SharedPreferences.getInstance();
      String token = _prefs.getString('access_token');
      User currentUser = User.fromPrefJson(jsonDecode(_prefs.get('current_user')));
      phone = currentUser.phone;
      if (token != null) {
        String requestUrl = '$baseUrl/websocket/tracker?access_token=$token'; // please note <<<<<
        StompClient stompClient = StompClient(
            config: StompConfig.SockJS(
                url: requestUrl,
                stompConnectHeaders: {
                  'Authorization' : 'Bearer $token', // please note <<<<<
                },
                webSocketConnectHeaders: {
                  'Authorization' : 'Bearer $token', // please note <<<<<
                },
                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;

                  clientUnSubscribeFn = _stompClient.subscribe(
                      destination: '/topic/client',  headers: {},
                      callback: (frame) {
                        // Received a frame for this subscription
                        print(frame.body);
                        clientController.add(frame.body);
                      }
                  );
                }
            )
        );
        stompClient.activate();
      }
    } catch(e) {
      print('An error occurred ${e.toString()}');
    }
  }


  sendClientMessage(String msg) async {
      if (_stompClient != null & _stompClient.connected) {
      _stompClient.send(
         destination: '/topic/client',
         body: msg,
        headers: {}
     );
  }
  }

À votre santé


0 commentaires