我正在构建Android应用程序,我正在努力处理重新连接。
所以流程是这样的:
1.连接您已经拥有的令牌
2.用户通过socket.io
连接到服务器
2.a)你有活跃的令牌
- 来自server的积极响应=>大家都很开心
2.b)您没有令牌或令牌不在数据库中
- 你必须从另一台服务器获得新令牌
- 提出了新的要求
- 作为响应,用户正在尝试再次连接
主要功能我正在运行以确保所有内容都已连接
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();
}
}
这就是我在新令牌到来之后正在运行的内容:
public void setSocketNewToken(){
AndroidApplication.isSocketConnected = false;
allowNextSocketConnection = true;
}
这是在连接成功后运行的:
public void setSocketConnected(){
Logger.log("SOCKET CONNECTED");
AndroidApplication.isSocketConnected = true;
}
第一次运行时一切运行顺畅,如果我杀死服务器并快速重新连接。但是只有在令牌过期和重新连接之后,有时它才会连接或者它正在连接但仍然循环通过“等待服务响应”并且它不应该因为我们已经有 isSocketConnected 真的。
有什么想法吗?
在输入大量日志之后,我现在可以看到 runMePlease()正在运行,我正在接收来自服务的更新并且它没有运行 IncomingHandler
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);
}
}
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(“等待服务响应”); 响应记录在 Emit.Listener已连接但AndroidApplication未运行 CONNECTED 块代码。
因此,在重新运行 runMePlease()之后,它首次正常工作,它的循环没有任何结束的可能性。
答案 0 :(得分:2)
我还没有查看详细的流程,但是当您从不同的线程访问isSocketConnected
和isServiceBound
时,您必须声明它们volatile
,以便所有写入都是从另一个线程读取它们时立即可见。否则,线程可能会读取这些变量的缓存值,即使它们已在另一个线程中已更改。
此外,如果您有多个可以调用runMePlease()
的线程,那么对allowNextSocketConnection
使用AtomicBoolean是有意义的,否则使用以下代码
if(allowNextSocketConnection) {
allowNextSocketConnection = false;
// ...
当if
为allowNextSocketConnection
时,两个帖子可以输入true
。为了防止这种情况,您可以使用compareAndSet(boolean expect, boolean update)
方法,这样只有一个线程可以进入if
。