【问题标题】:How to receive the message from stomp websocket with spring boot on android?如何在android上使用spring boot接收来自stomp websocket的消息?
【发布时间】:2022-01-18 13:14:51
【问题描述】:

我从https://spring.io/guides/gs/messaging-stomp-websocket/ 获得了简单的 WebSocket 示例

package com.example.chatservice.message;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

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

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/gs-guide-websocket").withSockJS();
    }
}
@Controller
public class ChatController {
    @MessageMapping("/hello")
    @SendTo("/topic/greetings")
    public Greeting greeting(HelloMessage message) throws Exception {
        return new Greeting("Hello from chat!");
    }
}

我想从 spring 服务器接收到 android 应用程序的 Greeting 消息。我使用https://github.com/NaikSoftware/StompProtocolAndroid 作为 stomp 客户端

package com.example.chatapp;

import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;

import org.java_websocket.WebSocket;

import ua.naiksoftware.stomp.Stomp;
import ua.naiksoftware.stomp.client.StompClient;

public class MainActivity extends AppCompatActivity {
    private StompClient mStompClient;
    public static  final String TAG="StompClient";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button view = (Button) findViewById(R.id.send_message);
        view.setOnClickListener(e->  new StompTask().execute(""));
    }

    private static class StompTask extends AsyncTask<String, Void, String> {
        private StompClient mStompClient;
        String TAG="LongOperation";

        @Override
        protected String doInBackground(String... params) {
            mStompClient = Stomp.over(WebSocket.class, "http://10.0.2.2:8080/gs-guide-websocket/websocket");
            mStompClient.connect();

            mStompClient.topic("/topic/greetings").subscribe(topicMessage -> {
                Log.d(TAG, topicMessage.getPayload());
            });

            mStompClient.lifecycle().subscribe(lifecycleEvent -> {
                switch (lifecycleEvent.getType()) {

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

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

                    case CLOSED:
                        Log.d(TAG, "Stomp connection closed");
                        break;
                }
            });

            return "Executed";
        }
    }
}

和连接

http://10.0.2.2:8080/gs-guide-websocket/websocket

有效,因为日志显示它已连接

2022-01-18 14:04:56.486 23717-23752/com.example.chatapp D/LongOperation: Stomp connection opened

但它不订阅主题:

mStompClient.topic("/topic/greetings").subscribe(topicMessage -> {
    Log.d(TAG, topicMessage.getPayload());
});

因为当我设置断点时,它永远不会命中它。

我怎样才能收到这条消息?

【问题讨论】:

    标签: java android spring spring-boot android-studio


    【解决方案1】:

    我认为一切看起来都很棒,除了 "http://10.0.2.2:8080/gs-guide-websocket/websocket" 对于 websocket 应该是 "ws://10.0.2.2:8080/gs-guide-websocket/websocket"

    图书馆的作者把这个放在他们的example code

    `mStompClient = Stomp.over(Stomp.ConnectionProvider.OKHTTP, "ws://" + ANDROID_EMULATOR_LOCALHOST + ":" + RestClient.SERVER_PORT + "/example-endpoint/websocket");` 
    

    【讨论】:

    • 我也试过这个。同样的结果:(。它连接到 websocket 但不订阅主题
    • 作者正在做的另一件事是.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()),这是您未指定的内容,尽管这可能不是问题。您是否尝试过记录各个步骤并查看记录器走了多远?后端是否有机会提供任何有意义的反馈?这是一个有趣的问题:D
    • 您是否关注this spring tutorial?如果是,您是否尝试过转至 ws://10.0.2.2:8080/gs-guide-websocket,甚至从您的 PC 上?
    • 我试过ws://10.0.2.2:8080/gs-guide-websocket它在android上给出Stomp connection closed。我在我的电脑上尝试了http://localhost:8080/gs-guide-websockethttp://localhost:8080/gs-guide-websocket/websocket。第一个返回Welcome to SockJS!,第二个返回Can "Upgrade" only to "WebSocket".
    • 在我的电脑 ws://blabla 上显示无法访问此站点
    【解决方案2】:

    首先我想你明白,如果你没有向指定的请求主题发送正确的消息,那么你将不会在这里得到任何东西-

    mStompClient.topic("/topic/greetings").subscribe(topicMessage -> {
        Log.d(TAG, topicMessage.getPayload());
    });
    

    今天我在发送消息时遇到了问题,

    mStompClient.send(REQUEST_TOPIC, requestAsString)
    

    我也没有收到任何订阅。问题是除了订阅接收消息的主题外,还必须订阅发送消息的主题-

    mStompClient.send(REQUEST_TOPIC, requestAsString)
                            .subscribeOn(Schedulers.io())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe(
                                    {
                                    //onComplete
                                    }, { error ->
                                      error.safeLog()
                                    })
    

    【讨论】:

    • 问题已经解决了。
    猜你喜欢
    • 2015-06-23
    • 2021-09-02
    • 2016-05-06
    • 2020-06-17
    • 2020-05-06
    • 2018-01-13
    • 1970-01-01
    • 2019-02-14
    • 2020-01-07
    相关资源
    最近更新 更多