0

I need help with connect on android to my WebSocket server based on Spring boot. Source code of this server I have taken https://spring.io/guides/gs/messaging-stomp-websocket/

Everything works fine on server and browser client on this sample, but if I use StompClient (https://github.com/NaikSoftware/StompProtocolAndroid) to connect on my socket I am getting mStompClient.isConnected() == false and conand mStompClient.send(...) doesn't send anything (?).

After few minutes socketweb server closes the connection and I get in my log: '~~ Stomp connection closed'. Web server locates on Heroku cloud system. There is my connecting code from android activity:

    private StompClient mStompClient;

     private void connectStomp(){
        mStompClient = Stomp.over(WebSocket.class, "wss://myserver/gs-guide-websocket");

        mStompClient.topic("/topic/greetings").subscribe(new Action1<StompMessage>() {
            @Override
            public void call(StompMessage stompMessage) {
                Log.w(TAG, "== "+stompMessage.getPayload());
            }
        });


        mStompClient.connect();

        mStompClient.lifecycle().subscribe(new Action1<LifecycleEvent>() {
            @Override
            public void call(LifecycleEvent lifecycleEvent) {
                switch (lifecycleEvent.getType()) {

                    case OPENED:
                        Log.w(TAG, "~~ Stomp connection opened");
                        break;

                    case ERROR:
                        Log.e(TAG, "~~ Error", lifecycleEvent.getException());
                        break;

                    case CLOSED:
                        Log.w(TAG, "~~ Stomp connection closed "+lifecycleEvent.getMessage());
                        break;
                }
            }
        });
    }

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        connectStomp();
    } 

   // Send test request to server
   public void onSend(View view){
        Log.w(TAG,"onSend: click");
        mStompClient.send("/app/hello","Test").subscribe(new Observer<Void>() {
            @Override
            public void onCompleted() {
                Log.w(TAG, "~~~~ onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                Log.w(TAG, "~~~~ onCompleted "+e.getMessage());
            }

            @Override
            public void onNext(Void aVoid) {
                Log.w(TAG, "~~~~ onNext ");
            }
        });
        if (mStompClient.isConnected()){
            mStompClient.send("/app/hello","test msg").subscribe();
            Log.w("aaaa : ","onCreate: connected");
        }
    }

It would be my mistake but if I connect to my server socket with spring boot WebSocketStompClient everithing works fine:

    private SockJsClient sockJsClient;

    private WebSocketStompClient stompClient;

    private final WebSocketHttpHeaders headers = new WebSocketHttpHeaders();

    @Before
    public void setup() {
        List<Transport> transports = new ArrayList<>();
        transports.add(new WebSocketTransport(new StandardWebSocketClient()));
        this.sockJsClient = new SockJsClient(transports);

        this.stompClient = new WebSocketStompClient(sockJsClient);
        this.stompClient.setMessageConverter(new MappingJackson2MessageConverter());
    }

    @Test
    public void getGreeting() throws Exception {

        final CountDownLatch latch = new CountDownLatch(1);
        final AtomicReference<Throwable> failure = new AtomicReference<>();

        StompSessionHandler handler = new TestSessionHandler(failure) {

            @Override
            public void afterConnected(final StompSession session, StompHeaders connectedHeaders) {
                session.subscribe("/topic/greetings", new StompFrameHandler() {
                    @Override
                    public Type getPayloadType(StompHeaders headers) {
                        return Greeting.class;
                    }

                    @Override
                    public void handleFrame(StompHeaders headers, Object payload) {
                        Greeting greeting = (Greeting) payload;

                        try {
                            System.out.println(greeting.getContent());
                            assertEquals("Hello, Spring!", greeting.getContent());
                        } catch (Throwable t) {
                            System.out.println(t.getMessage());
                            failure.set(t);
                        } finally {
                            session.disconnect();
                            latch.countDown();
                        }
                    }
                });
                try {
                    session.send("/app/hello", "Test");
                } catch (Throwable t) {
                    failure.set(t);
                    latch.countDown();
                }
            }
        };

        this.stompClient.connect("wss://myserver/gs-guide-websocket", this.headers, handler, 443);

        if (latch.await(10, TimeUnit.SECONDS)) {
            if (failure.get() != null) {
                throw new AssertionError("", failure.get());
            }
        }
        else {
            fail("Greeting not received");
        }

    }

    private class TestSessionHandler extends StompSessionHandlerAdapter {

        private final AtomicReference<Throwable> failure;


        public TestSessionHandler(AtomicReference<Throwable> failure) {
            this.failure = failure;
        }

        @Override
        public void handleFrame(StompHeaders headers, Object payload) {
            this.failure.set(new Exception(headers.toString()));
        }

        @Override
        public void handleException(StompSession s, StompCommand c, StompHeaders h, byte[] p, Throwable ex) {
            this.failure.set(ex);
        }

Any ideas? Thanks a lot!

Dmitriy S
  • 361
  • 1
  • 5
  • 14
  • I used the same Library in order to connect with Stomp based web socket. There were some configurations on the server side. On the android side, I was using URL as starting with "ws://" and ending with "websocket" like "ws://" + SERVER_URL + "/websocket". See this answer for server side: http://stackoverflow.com/a/41751897/5392825 – Yasir Tahir Apr 13 '17 at 14:04
  • You are absolutely right! It's solved my issue. – Dmitriy S Apr 13 '17 at 14:23
  • Kindly accept and up-vote my answer if it solved your issue. – Yasir Tahir Apr 16 '17 at 06:37

1 Answers1

3

I used the same Library in order to connect with Stomp based web socket. There were some configurations on the server side. On the android side, I was using URL as starting with "ws://" and ending with "websocket" like "ws://" + SERVER_URL + "/websocket".

See this answer for server side https://stackoverflow.com/a/41751897/5392825

Jimmy
  • 2,589
  • 21
  • 31
Yasir Tahir
  • 790
  • 1
  • 11
  • 31