Okhttp on Android connects to my websocket server but does not reflect outgoing messages

Asked

Viewed 93 times

1

Following this documentation https://spring.io/guides/gs/messaging-stomp-websocket/ created a small spring project capable of sending messages in real time using websockets, the web part stays this way

tela que emite as mensagens através de um websocket

so far everything is working perfectly, the problem starts when I try to connect a simple Android app from a single screen that should display the messages issued by the web platform, this connection is being made using Okhttp, below explain how works this connection.

tela do app que exibe as mensagens

When clicking the start button the connection to the server is made and the first text is displayed saying that the connection was successfully performed, this is the layout code:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
    android:id="@+id/start"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:text="Start !"
    android:layout_marginTop="40dp"
    android:textSize="17sp"/>
<TextView
    android:id="@+id/output"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@id/start"
    android:layout_centerHorizontal="true"
    android:textSize="16sp"
    android:layout_marginTop="30dp"/>
</RelativeLayout>

Next we have the Activity code where the connection is actually performed

package br.com.brendoniwata.websocketconnectiontest

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import okhttp3.*
import okio.ByteString

class MainActivity : AppCompatActivity() {

    private lateinit var client: OkHttpClient

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        client = OkHttpClient()

        start.setOnClickListener {
            start()
        }

    }

    private fun start() {
        val request = Request.Builder().url("ws://192.168.42.26:8080/gs-guide-websocket/websocket").build()
        val listener = EchoWebSocketListener()
        client.newWebSocket(request, listener)
    }

    private fun output(txt: String) {
        runOnUiThread {
            output.text = "${output.text}\n\n$txt".trimIndent()
        }
    }

    companion object {
        const val NORMAL_CLOSURE_STATUS = 1000;
    }

    inner class EchoWebSocketListener : WebSocketListener() {
        override fun onOpen(webSocket: WebSocket, response: Response) {
            output("connection established")
        }

        override fun onMessage(webSocket: WebSocket, text: String) {
            output("Receiving : $text")
        }

        override fun onMessage(webSocket: WebSocket, byte: ByteString) {
            output("Receiving : ${byte.hex()}")
        }

        override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
            webSocket.close(NORMAL_CLOSURE_STATUS, null)
            output("Closing : $code / $reason")
        }

        override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
            output("Erro : ${t.message}")
        }
    }
}

When clicking the start button is called the start() method which basically starts the websocket connection to the server, this connection occurs successfully, but when I go to the web platform and start inserting messages the application is not reflecting the messages inserted as it should. For further questions I will also leave the code of my controller, where is present the mapping of the request made by the web page and the mapping of the sending of the message to the customer.

package com.example.messagingstompwebsocket;

import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
import org.springframework.web.util.HtmlUtils;

@Controller
public class GreetingController {


    @MessageMapping("/hello")
    @SendTo("/topic/greetings")
    public Greeting greeting(HelloMessage message) throws Exception {
        return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
    }

}

Here in the controller basically the request is made to /hello and redirected to the registered clients as /topic/Greetings

1 answer

0

Well, I don’t have much experience with websockets on android, but reading the back documentation on Spring that you mentioned, she reports that:

STOMP is a subprotocol Operating on top of the Lower-level Websocket.

So maybe Okhttp does not have support for this specific communication. Also, analyzing the code I could not find the registration part in the Topics you mentioned (Topics/Greetings), what seems to be very important for this communication.

Looking a little I saw that the staff usually use the lib Stompprotocolandroid. In the Remapo also has a use case of how to implement.

Only the examples of use (in the android part) found in the repository already clarify my doubts regarding your code:

private StompClient mStompClient;
 
 // ...
 
 mStompClient = Stomp.over(Stomp.ConnectionProvider.OKHTTP, "ws://10.0.2.2:8080/example-endpoint/websocket");
 mStompClient.connect();
  
 mStompClient.topic("/topic/greetings").subscribe(topicMessage -> {
     Log.d(TAG, topicMessage.getPayload());
 });
  
 mStompClient.send("/topic/hello-msg-mapping", "My first STOMP message!").subscribe();
  
 // ...
 
 mStompClient.disconnect();

There’s a question here that might help you too: https://stackoverflow.com/questions/41675194/is-it-possible-to-use-stomp-with-okhttp3-websocket

I hope to have helped and if you find the solution, do not fail to inform us. Hugs ;)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.