gpt4 book ai didi

java - 应用程序 IncomingHandler 有时收不到服务消息

转载 作者:行者123 更新时间:2023-11-29 19:29:21 24 4
gpt4 key购买 nike

我正在构建 Android 应用程序,但我正在努力处理重新连接。

所以流程是这样的:
1. 连接已有的token
2. 用户通过socket.io连接到服务器
2.a) 你有活跃的代币
- 来自服务器的积极响应 => 每个人都很开心
2.b) 您没有 token 或 token 不在数据库中
- 你必须从另一台服务器获取新 token
- 提出了新的要求
- 作为响应,用户正在尝试再次连接

现在的代码:

申请

我正在运行的主要功能是确保一切都已连接

public static boolean isSocketConnected = false; //declared in AndroidApplication
public static boolean isServiceBound = false; //declared in AndroidApplication
public volatile boolean allowNextSocketConnection = true; //declared in same calss as _runMePlease_

private void runMePlease() { //running in new thread
if (AndroidApplication.isServiceBound) {
if (AndroidApplication.isSocketConnected) {
allowNextSocketConnection = false;
connected = true;
Logger.log("WE ARE CONNECTED");
} else {
if(isNetworkAvailable()){
if(allowNextSocketConnection) {
allowNextSocketConnection = false;
AndroidApplication.sendDataToService(CONNECT);
} else {
Logger.log("WAITING FOR SERVICE RESPONSE");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
runMePlease();
}
}

这就是我在收到新 token 后运行的内容:

public void setSocketNewToken(){
AndroidApplication.isSocketConnected = false;
allowNextSocketConnection = true;
}

这是在成功连接后运行的:

public void setSocketConnected(){
Logger.log("SOCKET CONNECTED");
AndroidApplication.isSocketConnected = true;
}

第一次运行一切顺利,如果我终止服务器并快速重新连接它。但仅在 token 过期并重新连接后,有时它没有连接或正在连接但仍在循环“等待服务响应”,这不应该因为我们已经有isSocketConnected是真的。

有什么想法吗?

编辑

在放置大量日志后,我现在可以看到 runMePlease() 正在工作的某个点,我正在从服务接收更新,但它没有运行 IncomingHandler .

AndroidApplication fragment (在实现 AtomicBoolean 之后)

static class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case CONNECTED:
Logger.log("New connect");
isSocketConnected.set(true);
connectionManager.setSocketConnected();
break;
case DISCONNECTED:
Logger.log("Disconnect");
connectionManager.setSocketDisconnected();
break;
case REFRESH_TOKEN:
Logger.log("Refresh token");
new Thread("Try2Connect") {
@Override
public void run() {
getNewToken();
}
}.start();

break;
default:
super.handleMessage(msg);
}
}

服务 fragment

public Emitter.Listener connected = new Emitter.Listener() {
@Override
public void call(Object... args) {
Logger.log("CONNECT!!!!!!!!!");
messengerSynchronizer.sendToApplication(CONNECTED, ""); // sending data back to AndroidApplication
}
};

所以基本上在我运行 runMePlease() 并等待 Logger.log("WAITING FOR SERVICE RESPONSE"); 之后,响应记录在 Emit.Listener connected 但 AndroidApplication 未运行 CONNECTED block 代码。
因此,它第一次运行完美,在重新运行 runMePlease() 后,它会循环,没有任何结束的可能性。

最佳答案

我没有看过详细的流程,但是当你从不同的线程访问 isSocketConnectedisServiceBound 时,你必须将它们声明为 volatile 所以当从另一个线程读取它们时,所有对它的写入都立即可见。否则线程可能会读取这些变量的缓存值,即使它们已经在另一个线程中被更改。

此外,当您有多个线程可以调用 runMePlease() 时,将 AtomicBoolean 用于 allowNextSocketConnection 是有意义的,否则使用以下代码

if(allowNextSocketConnection) {
allowNextSocketConnection = false;
// ...

allowNextSocketConnectiontrue 时,两个线程可以进入 if。为防止这种情况,您可以使用 compareAndSet(boolean expect, boolean update) 方法,这样只有一个线程可以进入 if

关于java - 应用程序 IncomingHandler 有时收不到服务消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40441771/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com