java - 我正在尝试使用 STOMP 将数据从浏览器发送到 Android 移动应用程序,并且遇到 IP 地址问题
问题描述
我对 STOMP 很陌生,只学了几个星期。我一直在尝试使用 STOMP 将数据从浏览器发送到 Android 移动应用程序,到目前为止,我已经成功地将数据从浏览器发送到 Android 模拟器,但是如果我在手机上尝试,应用程序会崩溃。
我做了什么:
我在运行 Android Studio 模拟器之前运行了 Spring Boot Websocket Server
对运行服务器的手机和笔记本电脑使用相同的 wifi。
我的代码基于 xlui/WebSocketExample。(在谷歌上搜索,你可以找到代码)
我在 Android Studio 中使用 NaikSoftware/StompProtocolAndroid,Android 客户端使用在 Android 上实现协议 STOMP 的 StompProtocolAndroid 订阅或发送消息到服务器。
Spring Boot WebSocket 服务器在 Intelliji 完整版上运行。
从 10.0.2.2/8080/im/websocket 更改为 Stomp.over(Stomp.ConnectionProvider.OKHTTP, "ws://MY LAPTOP IP ADDRESS/8080/im/websocket");
我在 Android Studio 中用于广播活动的代码:
package app.xlui.example.im.activities;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Arrays;
import app.xlui.example.im.R;
import app.xlui.example.im.conf.Const;
import app.xlui.example.im.util.StompUtils;
import ua.naiksoftware.stomp.Stomp;
import ua.naiksoftware.stomp.StompClient;
import ua.naiksoftware.stomp.dto.StompCommand;
import ua.naiksoftware.stomp.dto.StompHeader;
import ua.naiksoftware.stomp.dto.StompMessage;
@SuppressWarnings({"FieldCanBeLocal", "ResultOfMethodCallIgnored", "CheckResult"})
public class BroadcastActivity extends AppCompatActivity {
private Button broadcastButton;
private Button groupButton;
private Button chatButton;
private EditText nameText;
private Button sendButton;
private TextView resultText;
private EditText nameput;
private void init() {
broadcastButton = findViewById(R.id.broadcast);
broadcastButton.setEnabled(false);
groupButton = findViewById(R.id.groups);
chatButton = findViewById(R.id.chat);
nameText = findViewById(R.id.name);
sendButton = findViewById(R.id.send);
resultText = findViewById(R.id.show);
nameput=findViewById(R.id.name2);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broadcast);
this.init();
StompClient stompClient = Stomp.over(Stomp.ConnectionProvider.OKHTTP, "ws://MY LAPTOP IP ADDRESS/im/websocket");
StompUtils.lifecycle(stompClient);
Toast.makeText(this, "Start connecting to server", Toast.LENGTH_SHORT).show();
// Connect to WebSocket server
stompClient.connect();
// 订阅消息
Log.i(Const.TAG, "Subscribe broadcast endpoint to receive response");
stompClient.topic(Const.broadcastResponse).subscribe(stompMessage -> {
JSONObject jsonObject = new JSONObject(stompMessage.getPayload());
Log.i(Const.TAG, "Receive: " + stompMessage.getPayload());
runOnUiThread(() -> {
try {
resultText.append(jsonObject.getString("response") + "\n");
nameput.setText(jsonObject.getString("response"));
} catch (JSONException e) {
e.printStackTrace();
}
});
});
sendButton.setOnClickListener(v -> {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("name", nameText.getText());
} catch (JSONException e) {
e.printStackTrace();
}
stompClient.send(new StompMessage(
// Stomp command
StompCommand.SEND,
// Stomp Headers, Send Headers with STOMP
// the first header is required, and the other can be customized by ourselves
Arrays.asList(
new StompHeader(StompHeader.DESTINATION, Const.broadcast),
new StompHeader("authorization", "this is a token generated by your code!")
),
// Stomp payload
jsonObject.toString())
).subscribe();
nameText.setText("");
});
groupButton.setOnClickListener(v -> {
Intent intent = new Intent();
intent.setClass(BroadcastActivity.this, GroupActivity.class);
startActivity(intent);
this.finish();
});
chatButton.setOnClickListener(v -> {
Intent intent = new Intent();
intent.setClass(BroadcastActivity.this, ChatActivity.class);
startActivity(intent);
this.finish();
});
}
}
我在 Android Studio 中的 Const 活动代码:
public class Const {
public static final String TAG = "xlui";
public static final String placeholder = "placeholder";
/**
* <code>im</code> in address is the endpoint configured in server.
* If you are using AVD provided by Android Studio, you should uncomment the upper address.
* If you are using Genymotion, nothing else to do.
* If you are using your own phone, just change the server address and port.
*/
private static final String address = "ws://10.0.2.2:8080/im/websocket";//for android vm
//public static final String address = "ws://10.0.3.2:8080/im/websocket";//for Genymotion
public static final String broadcast = "/broadcast";
public static final String broadcastResponse = "/b";
// replace {@code placeholder} with group id
public static final String group = "/group/" + placeholder;
public static final String groupResponse = "/g/" + placeholder;
public static final String chat = "/chat";
// replace {@code placeholder} with user id
public static final String chatResponse = "/user/" + placeholder + "/msg";
}
我在 Android Studio 中用于 StompUtils 活动的代码:
import android.util.Log;
import app.xlui.example.im.conf.Const;
import ua.naiksoftware.stomp.StompClient;
import static app.xlui.example.im.conf.Const.TAG;
public class StompUtils {
@SuppressWarnings({"ResultOfMethodCallIgnored", "CheckResult"})
public static void lifecycle(StompClient stompClient) {
stompClient.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;
}
});
}
}
我不知道我做错了什么,我有什么建议请说。
解决方案
推荐阅读
- git - 如何合并远程跟踪无 github 分支?
- javascript - 在 QUnit 测试中,只有在测试运行之前获得引用时才会触发 click 事件
- excel - 将字符串变量设置为单元格——应用程序定义的或对象定义的错误
- sql - 如何修复“无法删除对象 'Teams',因为它被 FOREIGN KEY 约束引用”
- graphql - 如何在一个类型中添加多个解析器(Apollo-server)
- java - Collections.sort 不改变列表
- java - MouseClicked() 方法不适用于寻路算法?
- sql - 如何避免使用 for next 方法获取行数
- angular - Angular SSR - 要导入的文件未找到或不可读:
- php - 查询所有年份,但只查询一次