简体   繁体   中英

Flutter websocket with Spring-boot backend

Alright, Flutter has the WebSocket recipe in the cookbook ( here ). And that works great against the websocket.org test server.

The thing is I want to connect with my own WebSocket server. So I first used this tutorial from SpringBoot.

Trying to make a request from the app (I am using the emulator here) to the spring boot backend did not work. I then started tinkering and removed STOMP from the spring boot backend and left it with a simple WebSocket passing strings. It works when using postman or even a webpage but it doesn't work from the app

The current state is present at this GitHub (both the spring boot and flutter projects): https://github.com/Flavsditz/websocket_sandbox

Does anyone have any tips here?

I appreciate it!

After a bit of consideration, I found the issue:

The problem is that my spring-boot server was on localhost , but the flutter (which is also the android emulator) has its own loopback service. So calling localhost inside the Flutter program is referring to another place instead of the one I wanted.

I've substituted the localhost for the ip 10.0.2.2 which is an alias to the host PC which is set up to help in development.

For more infos check this answer: here

Of course if you wanted to test from a real device than one would need to publish the backend for the outside, so this answer might be better: here

In flutter-websocket_test/lib/message_page.dart you have the following on line 6-7:

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

You have locahost instead of localhost , so try changing this and see if it works.

Thanks for the solution, For the side note if you want to test in real device than,

  1. Both real device and pc has to in same network.
    (In my case I am using hotspot from my phone to pc)

  2. Get IP from your pc with cmd, type ipconfig to get IP.
    (In my case its IPv4 Address. . . . . . . . . . . : 192.168.43.423 )

  3. Now paste your IP instead of localhost
    Eg.

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

For those using

stomp_dart_client: ^0.3.7

with sockjs, Remember to pass the token to the header

 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: {} ); } }

Also do not forget to update the Spring security configurations and web socket configurations

 @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 }

Cheers

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