在工作中遇到一个业务,需要在方法中需要送过socket远程调用某个接口,然后这个远程接口采用的是流式返回,需要需要在远程接口全部返回完毕后,本地这个接口才返回对应的数据,怎么做呢?
一开始用一个方式完成了逻辑,但是感觉这样子写不太好,后面研究又发现了另一个方法。
===========================
两种方法介绍如下
一开始我采用的是在类中写一个boolean标识符,默认为false,然后在socket的监听器的onMessage方法中判断是否可以返回,可以的话就将这个boolean标识符设置为true,然后在调用socket这个方法返回前通过while循环检查这个boolean标识符,如果boolean不为true就不返回,但是我也考虑到了超时过长问题,所以这个while判断条件包括了超过25就立马返回的逻辑,同时由于直接while容易造成该线程闲置等待,所以在while循环了写了Thread.sleep(500)。
但是这个逻辑有点太麻烦了,代码写起来也不太好看。
后面研究发现可以 【使用CountDownLatch
来实现阻塞等待】
例如这样,代码如下
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import java.util.concurrent.CountDownLatch;
public class WebSocketBlockingExample {
public Object connectWebSocket() {
Object result = null;
CountDownLatch latch = new CountDownLatch(1);
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("ws://your-websocket-url").build();
client.newWebSocket(request, new WebSocketListener() {
@Override
public void onOpen(WebSocket webSocket, okhttp3.Response response) {
// WebSocket 连接打开时的处理逻辑
}
@Override
public void onMessage(WebSocket webSocket, String text) {
// 接收到消息时的处理逻辑
// 检查消息是否满足返回条件,如果满足则设置结果并释放阻塞
if (isReturnConditionMet(text)) {
result = parseResult(text);
latch.countDown();
}
}
@Override
public void onClosing(WebSocket webSocket, int code, String reason) {
// WebSocket 正在关闭时的处理逻辑
}
@Override
public void onClosed(WebSocket webSocket, int code, String reason) {
// WebSocket 关闭后的处理逻辑
}
@Override
public void onFailure(WebSocket webSocket, Throwable t, okhttp3.Response response) {
// 连接失败时的处理逻辑
}
});
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return result;
}
private boolean isReturnConditionMet(String message) {
// 在此处编写判断消息是否满足返回条件的逻辑
return false;
}
private Object parseResult(String text) {
// 在此处解析消息并返回结果
return null;
}
public static void main(String[] args) {
WebSocketBlockingExample example = new WebSocketBlockingExample();
Object result = example.connectWebSocket();
// 处理返回的结果
}
}