Update:修改为工厂模式创建实例
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
package cn.montaro.aria2.client.websocket;
|
||||
|
||||
|
||||
import cn.montaro.aria2.api.Aria2Client;
|
||||
import cn.montaro.aria2.client.websocket.constants.Aria2Method;
|
||||
import cn.montaro.aria2.Aria2Client;
|
||||
import cn.montaro.aria2.constants.Aria2MethodName;
|
||||
import cn.montaro.aria2.client.websocket.exception.Aria2WebSocketClientConnectTimeoutException;
|
||||
import cn.montaro.aria2.client.websocket.exception.Aria2WebSocketClientException;
|
||||
import cn.montaro.aria2.client.websocket.exception.Aria2WebSocketClientTimeoutException;
|
||||
@@ -27,7 +27,7 @@ import java.util.concurrent.TimeUnit;
|
||||
* @date 2021/12/15
|
||||
*/
|
||||
@Slf4j
|
||||
public class Aria2WebSocketClient extends WebSocketClient implements Aria2Client {
|
||||
public class Aria2WebSocketClient extends WebSocketClient {
|
||||
|
||||
private Gson gson = null;
|
||||
private Aria2WebSocketConfig config = null;
|
||||
@@ -147,6 +147,12 @@ public class Aria2WebSocketClient extends WebSocketClient implements Aria2Client
|
||||
return result.getResult();
|
||||
}
|
||||
|
||||
private <T> T getResult(Aria2WebSocketRequest request) {
|
||||
String id = request.getId();
|
||||
this.sendRequest(request);
|
||||
return this.waitResult(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理id映射关系
|
||||
*
|
||||
@@ -160,90 +166,9 @@ public class Aria2WebSocketClient extends WebSocketClient implements Aria2Client
|
||||
|
||||
public String addUri(String[] uris) {
|
||||
List<String> uriList = Arrays.asList(uris);
|
||||
return this.addUri(uriList, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String addUri(List<String> uris, Map<String, String> option, Integer position) {
|
||||
Aria2WebSocketRequest request = this.buildRequest(
|
||||
Aria2Method.ADD_URI,
|
||||
new TypeToken<Aria2WebSocketResponse<String>>() {
|
||||
}.getType(),
|
||||
uris,
|
||||
option,
|
||||
position
|
||||
);
|
||||
String id = request.getId();
|
||||
this.sendRequest(request);
|
||||
return this.waitResult(id);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> listMethods() {
|
||||
Aria2WebSocketRequest request = this.buildRequest(
|
||||
Aria2Method.LIST_METHODS,
|
||||
new TypeToken<Aria2WebSocketResponse<List<String>>>() {
|
||||
}.getType()
|
||||
);
|
||||
String id = request.getId();
|
||||
this.sendRequest(request);
|
||||
return this.waitResult(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String remove(String s) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String forceRemove(String s) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pause(String s) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String forcePause(String s) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String pauseAll() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String forcePauseAll() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String unpause(String s) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tellStatus(String gid) {
|
||||
|
||||
}
|
||||
|
||||
// --------------WebSocket Client--------------
|
||||
|
||||
@Override
|
||||
public void tellStopped(Integer offset, Integer num, String[] keys) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changePosition(String gid, Integer pos, String how) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onOpen(ServerHandshake serverHandshake) {
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package cn.montaro.aria2.client.websocket;
|
||||
|
||||
import cn.montaro.aria2.client.websocket.constants.WebSocketProtocol;
|
||||
import cn.montaro.aria2.constants.WebSocketProtocol;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
package cn.montaro.aria2.client.websocket;
|
||||
|
||||
import cn.montaro.aria2.annotation.Aria2Method;
|
||||
import cn.montaro.aria2.client.websocket.exception.Aria2WebSocketClientException;
|
||||
import com.google.gson.*;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.java_websocket.client.WebSocketClient;
|
||||
import org.java_websocket.handshake.ServerHandshake;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URI;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
*
|
||||
* @author ZhangJiaYu
|
||||
* @date 2021/12/22
|
||||
*/
|
||||
@Slf4j
|
||||
public class Aria2WebSocketProxy implements InvocationHandler {
|
||||
|
||||
private final Gson gson;
|
||||
private final WebSocketImpl webSocket;
|
||||
private final Aria2WebSocketConfig config;
|
||||
|
||||
@SneakyThrows
|
||||
public Aria2WebSocketProxy(Aria2WebSocketConfig config) {
|
||||
this.config = config;
|
||||
this.gson = new GsonBuilder().create();
|
||||
this.webSocket = new WebSocketImpl(config.getURI());
|
||||
this.webSocket.connectBlocking(config.getTimeout(), TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
Aria2Method aria2Method = method.getDeclaredAnnotation(Aria2Method.class);
|
||||
String methodName = aria2Method.value();
|
||||
Aria2WebSocketRequest request = this.buildRequest(methodName, args);
|
||||
Object o = this.sendRequest(request, method.getGenericReturnType());
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* 序列化参数
|
||||
*
|
||||
* @param args
|
||||
* @return
|
||||
*/
|
||||
private JsonElement serializeArguments(Object[] args) {
|
||||
ArrayList<Object> arguments = new ArrayList<>();
|
||||
if (args != null && args.length != 0) {
|
||||
arguments = new ArrayList<>(Arrays.asList(args));
|
||||
}
|
||||
String secret = "token:";
|
||||
if (config.getSecret() != null) {
|
||||
secret += config.getSecret();
|
||||
}
|
||||
arguments.add(0, secret);
|
||||
int size = arguments.size();
|
||||
ListIterator<Object> listIterator = arguments.listIterator(size);
|
||||
while (listIterator.hasPrevious()) {
|
||||
Object previous = listIterator.previous();
|
||||
if (previous == null) {
|
||||
listIterator.remove();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return gson.toJsonTree(arguments);
|
||||
}
|
||||
|
||||
private String serializeRequest(Aria2WebSocketRequest request) {
|
||||
return this.gson.toJson(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建请求体
|
||||
*
|
||||
* @param methodName 调用方法名称 如 aria2.addUri
|
||||
* @param args 参数
|
||||
* @return
|
||||
*/
|
||||
private Aria2WebSocketRequest buildRequest(String methodName, Object[] args) {
|
||||
Aria2WebSocketRequest request = new Aria2WebSocketRequest();
|
||||
String id = UUID.randomUUID().toString();
|
||||
request.setId(id);
|
||||
request.setMethod(methodName);
|
||||
request.setParams(serializeArguments(args));
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
private <T> T sendRequest(Aria2WebSocketRequest request, Type resultType) {
|
||||
String id = request.getId();
|
||||
webSocket.send(serializeRequest(request));
|
||||
JsonObject returnResult = null;
|
||||
while ((returnResult = this.webSocket.getResponse(id)) == null) {
|
||||
Aria2WebSocketClientException exception = this.webSocket.getException(id);
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
}
|
||||
JsonElement result = returnResult.get("result");
|
||||
return gson.fromJson(result, resultType);
|
||||
}
|
||||
|
||||
////////////////////////// WebSocket Client //////////////////////////
|
||||
|
||||
private class WebSocketImpl extends WebSocketClient {
|
||||
|
||||
private final Map<String, JsonObject> resultValueMap = new HashMap<>();
|
||||
private final Map<String, Aria2WebSocketClientException> resultExceptionMap = new HashMap<>();
|
||||
|
||||
public WebSocketImpl(URI serverUri) {
|
||||
super(serverUri);
|
||||
}
|
||||
|
||||
public JsonObject getResponse(String id) {
|
||||
JsonObject result = resultValueMap.get(id);
|
||||
if (result != null) {
|
||||
resultValueMap.remove(id);
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Aria2WebSocketClientException getException(String id) {
|
||||
Aria2WebSocketClientException exception = resultExceptionMap.get(id);
|
||||
if (exception != null) {
|
||||
resultExceptionMap.remove(id);
|
||||
return exception;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOpen(ServerHandshake handshakedata) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(String message) {
|
||||
JsonElement jsonElement = JsonParser.parseString(message);
|
||||
JsonObject jsonObject = jsonElement.getAsJsonObject();
|
||||
String id = jsonObject.get("id").getAsString();
|
||||
if (id == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
JsonObject error = jsonObject.getAsJsonObject("error");
|
||||
if (error != null) {
|
||||
String errorMessage = error.get("message").getAsString();
|
||||
this.resultExceptionMap.put(id, new Aria2WebSocketClientException(errorMessage));
|
||||
return;
|
||||
}
|
||||
this.resultValueMap.put(id, jsonObject);
|
||||
} catch (Exception e) {
|
||||
this.resultExceptionMap.put(id, new Aria2WebSocketClientException(e));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClose(int code, String reason, boolean remote) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(Exception ex) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,10 @@
|
||||
package cn.montaro.aria2.client.websocket;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
package cn.montaro.aria2.client.websocket.constants;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
* Aria2可调用方法名称
|
||||
*
|
||||
* @author ZhangJiaYu
|
||||
* @date 2021/12/14
|
||||
*/
|
||||
public class Aria2Method {
|
||||
|
||||
private final static String ARIA2 = "aria2.";
|
||||
private final static String SYSTEM = "system.";
|
||||
|
||||
public final static String ADD_URI = ARIA2 + "addUri";
|
||||
public final static String ADD_TORRENT = ARIA2 + "addTorrent";
|
||||
public final static String ADD_METALINK = ARIA2 + "addMetalink";
|
||||
|
||||
public final static String REMOVE = ARIA2 + "remove";
|
||||
public final static String FORCE_REMOVE = ARIA2 + "forceRemove";
|
||||
|
||||
public final static String PAUSE = ARIA2 + "pause";
|
||||
public final static String UNPAUSE = ARIA2 + "unpause";
|
||||
public final static String PAUSE_ALL = ARIA2 + "pauseAll";
|
||||
public final static String UNPAUSE_ALL = ARIA2 + "unpauseAll";
|
||||
public final static String FORCE_PAUSE = ARIA2 + "forcePause";
|
||||
public final static String FORCE_PAUSE_ALL = ARIA2 + "forcePauseAll";
|
||||
|
||||
public final static String TELL_STATUS = ARIA2 + "tellStatus";
|
||||
public final static String TELL_ACTIVE = ARIA2 + "tellActive";
|
||||
public final static String TELL_WAITING = ARIA2 + "tellWaiting";
|
||||
public final static String TELL_STOPPED = ARIA2 + "tellStopped";
|
||||
|
||||
public final static String GET_URIS = ARIA2 + "getUris";
|
||||
public final static String GET_FILES = ARIA2 + "getFiles";
|
||||
public final static String GET_PEERS = ARIA2 + "getPeers";
|
||||
public final static String GET_OPTION = ARIA2 + "getOption";
|
||||
public final static String GET_SERVERS = ARIA2 + "getServers";
|
||||
public final static String GET_VERSION = ARIA2 + "getVersion";
|
||||
public final static String GET_GLOBAL_STAT = ARIA2 + "getGlobalStat";
|
||||
public final static String GET_SESSION_INFO = ARIA2 + "getSessionInfo";
|
||||
|
||||
public final static String CHANGE_URI = ARIA2 + "changeUri";
|
||||
public final static String CHANGE_OPTION = ARIA2 + "changeOption";
|
||||
public final static String CHANGE_POSITION = ARIA2 + "changePosition";
|
||||
public final static String CHANGE_GLOBAL_OPTION = ARIA2 + "changeGlobalOption";
|
||||
|
||||
public final static String PURGE_DOWNLOAD_RESULT = ARIA2 + "purgeDownloadResult";
|
||||
public final static String REMOVE_DOWNLOAD_RESULT = ARIA2 + "removeDownloadResult";
|
||||
|
||||
public final static String SHUTDOWN = ARIA2 + "shutdown";
|
||||
public final static String SAVE_SESSION = ARIA2 + "saveSession";
|
||||
public final static String FORCE_SHUTDOWN = ARIA2 + "forceShutdown";
|
||||
|
||||
public final static String MULTICALL = SYSTEM + "multicall";
|
||||
public final static String LIST_METHODS = SYSTEM + "listMethods";
|
||||
public final static String LIST_NOTIFICATIONS = SYSTEM + "listNotifications";
|
||||
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
package cn.montaro.aria2.client.websocket.constants;
|
||||
|
||||
/**
|
||||
* Description:
|
||||
*
|
||||
* @author ZhangJiaYu
|
||||
* @date 2021/12/15
|
||||
*/
|
||||
public class WebSocketProtocol {
|
||||
|
||||
public final static String PROTOCOL_WS = "ws";
|
||||
public final static String PROTOCOL_WSS = "wss";
|
||||
|
||||
}
|
||||
+1
@@ -9,6 +9,7 @@ package cn.montaro.aria2.client.websocket.exception;
|
||||
public class Aria2WebSocketClientException extends RuntimeException {
|
||||
|
||||
public Aria2WebSocketClientException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Aria2WebSocketClientException(String message) {
|
||||
|
||||
Reference in New Issue
Block a user