Update:删除无效文件,添加Http方式

This commit is contained in:
SparkZhang 2022-02-02 18:11:54 +08:00
parent 585edaf3b7
commit b45e3863ca
15 changed files with 179 additions and 413 deletions

View File

@ -15,6 +15,12 @@
<dependencies> <dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-http</artifactId>
<version>5.7.6</version>
</dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
@ -28,7 +34,6 @@
<version>1.18.20</version> <version>1.18.20</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.code.gson</groupId> <groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId> <artifactId>gson</artifactId>

View File

@ -1,6 +1,6 @@
package cn.montaro.aria2; package cn.montaro.aria2;
import cn.montaro.aria2.client.websocket.Aria2WebSocketConfig; import cn.montaro.aria2.client.http.Aria2HttpProxy;
import cn.montaro.aria2.client.websocket.Aria2WebSocketProxy; import cn.montaro.aria2.client.websocket.Aria2WebSocketProxy;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
@ -17,10 +17,17 @@ public class Aria2ClientFactory {
return Thread.currentThread().getContextClassLoader(); return Thread.currentThread().getContextClassLoader();
} }
public static Aria2Client webSocketClient(Aria2WebSocketConfig config) { public static Aria2Client webSocketClient(Aria2Config config) {
ClassLoader classLoader = getClassLoader(); ClassLoader classLoader = getClassLoader();
Aria2WebSocketProxy proxy = new Aria2WebSocketProxy(config); Aria2WebSocketProxy proxy = new Aria2WebSocketProxy(config);
Aria2Client webSocketClient = (Aria2Client) Proxy.newProxyInstance(classLoader, new Class[]{Aria2Client.class}, proxy); Aria2Client webSocketClient = (Aria2Client) Proxy.newProxyInstance(classLoader, new Class[]{Aria2Client.class}, proxy);
return webSocketClient; return webSocketClient;
} }
public static Aria2Client httpClient(Aria2Config config) {
ClassLoader classLoader = getClassLoader();
Aria2HttpProxy proxy = new Aria2HttpProxy(config);
Aria2Client httpClient = (Aria2Client) Proxy.newProxyInstance(classLoader, new Class[]{Aria2Client.class}, proxy);
return httpClient;
}
} }

View File

@ -1,20 +1,14 @@
package cn.montaro.aria2.client.websocket; package cn.montaro.aria2;
import cn.montaro.aria2.constants.WebSocketProtocol; import cn.montaro.aria2.constants.Aria2Protocol;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.net.URI; import java.net.URI;
/**
* Description:
*
* @author ZhangJiaYu
* @date 2021/12/15
*/
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
public class Aria2WebSocketConfig { public class Aria2Config {
/** /**
* 服务器地址 默认localhost * 服务器地址 默认localhost
@ -37,13 +31,17 @@ public class Aria2WebSocketConfig {
*/ */
private Long timeout = 10000L; private Long timeout = 10000L;
/** /**
* 连接协议 默认ws * 连接协议 默认http
* @see WebSocketProtocol *
* @see Aria2Protocol
*/ */
private String protocol = WebSocketProtocol.PROTOCOL_WS; private String protocol = Aria2Protocol.Http.HTTP;
public URI getURI() { public URI getURI() {
return URI.create(protocol + "://" + host + ":" + port + "/" + path); return URI.create(url());
} }
public String url() {
return protocol + "://" + host + ":" + port + "/" + path;
}
} }

View File

@ -0,0 +1,90 @@
package cn.montaro.aria2.client.http;
import cn.hutool.http.HttpUtil;
import cn.montaro.aria2.Aria2Config;
import cn.montaro.aria2.annotation.Aria2Method;
import com.google.gson.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.ListIterator;
import java.util.UUID;
public class Aria2HttpProxy implements InvocationHandler {
private final Gson gson;
private Aria2Config config;
public Aria2HttpProxy(Aria2Config config) {
this.config = config;
this.gson = new GsonBuilder().create();
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Aria2Method aria2Method = method.getDeclaredAnnotation(Aria2Method.class);
String methodName = aria2Method.value();
Type resultType = method.getGenericReturnType();
String body = this.serialize(methodName, args);
String json = this.request(body);
Object result = this.deserialize(json, resultType);
return result;
}
private String serialize(String methodName, Object[] args) {
Aria2HttpRequest request = new Aria2HttpRequest();
request.setId(UUID.randomUUID().toString());
request.setMethod(methodName);
request.setParams(serializeArguments(args));
return gson.toJson(request);
}
/**
* 序列化参数
*
* @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 request(String body) {
String url = config.url();
String json = HttpUtil.post(url, body);
return json;
}
private Object deserialize(String json, Type resultType) {
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
JsonObject result = jsonObject.get("result").getAsJsonObject();
if (resultType.equals(String.class)) {
return result.toString();
}
return gson.fromJson(result, resultType);
}
}

View File

@ -0,0 +1,16 @@
package cn.montaro.aria2.client.http;
import com.google.gson.JsonElement;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@Accessors(chain = true)
public class Aria2HttpRequest implements Serializable {
private String id;
private String jsonrpc = "2.0";
private String method;
private JsonElement params;
}

View File

@ -1,219 +0,0 @@
package cn.montaro.aria2.client.websocket;
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;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.exceptions.WebsocketNotConnectedException;
import org.java_websocket.handshake.ServerHandshake;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
/**
* Description:
*
* @author ZhangJiaYu
* @date 2021/12/15
*/
@Slf4j
public class Aria2WebSocketClient extends WebSocketClient {
private Gson gson = null;
private Aria2WebSocketConfig config = null;
private final Map<String, Aria2WebSocketResponse> resultValueMap = new ConcurrentHashMap<>();
private final Map<String, Type> resultTypeMap = new ConcurrentHashMap<>();
private final Map<String, Aria2WebSocketClientException> resultExceptionMap = new ConcurrentHashMap<>();
@SneakyThrows
public Aria2WebSocketClient(Aria2WebSocketConfig config) {
super(config.getURI());
this.connectBlocking(config.getTimeout(), TimeUnit.MILLISECONDS);
this.config = config;
this.gson = new GsonBuilder().create();
if (!this.isOpen()) {
throw new Aria2WebSocketClientConnectTimeoutException(config.getURI(), config.getTimeout());
}
}
private JsonElement getJsonElement(Object... val) {
ArrayList<Object> params = new ArrayList<>(Arrays.asList(val));
String secret = "token:";
if (config.getSecret() != null) {
secret += config.getSecret();
}
params.add(0, secret);
int size = params.size();
ListIterator<Object> listIterator = params.listIterator(size);
while (listIterator.hasPrevious()) {
Object previous = listIterator.previous();
if (previous == null) {
listIterator.remove();
} else {
break;
}
}
return gson.toJsonTree(params);
}
/**
* 通过参数构建请求
*
* @param method Aria2调用方法
* @param resultType 返回结果类型
* @return 请求
*/
private Aria2WebSocketRequest buildRequest(String method, Type resultType, Object... params) {
Aria2WebSocketRequest request = new Aria2WebSocketRequest();
String id = UUID.randomUUID().toString();
request.setId(id);
request.setMethod(method);
request.setParams(this.getJsonElement(params));
this.saveMap(id, resultType);
return request;
}
/**
* 序列化请求为Json格式
*
* @param request 请求参数
* @return 序列化成Json的请求内容
*/
private String serialize(Aria2WebSocketRequest request) {
return this.gson.toJson(request);
}
/**
* 保存id关系映射结果
*
* @param id id
* @param resultType 结果结果类型
*/
private void saveMap(String id, Type resultType) {
// this.resultValueMap.put(id, null);
this.resultTypeMap.put(id, resultType);
// this.resultExceptionMap.put(id, null);
}
/**
* 发送请求
*
* @param request 请求
*/
private void sendRequest(Aria2WebSocketRequest request) {
String body = this.serialize(request);
log.debug("Send Request:{}", body);
try {
this.send(body);
} catch (WebsocketNotConnectedException e) {
}
}
/**
* 等待结果返回
*
* @param id id
* @param <T> 返回结果类型
* @return
*/
@SneakyThrows
private <T> T waitResult(String id) {
Aria2WebSocketResponse<T> result = null;
Date startTime = new Date();
while ((result = this.resultValueMap.get(id)) == null) {
Aria2WebSocketClientException exception = this.resultExceptionMap.get(id);
if (exception != null) {
this.clearMap(id);
throw exception;
}
boolean isStop = (new Date().getTime() - startTime.getTime()) >= this.config.getTimeout();
if (isStop) {
throw new Aria2WebSocketClientTimeoutException();
}
}
this.clearMap(id);
return result.getResult();
}
private <T> T getResult(Aria2WebSocketRequest request) {
String id = request.getId();
this.sendRequest(request);
return this.waitResult(id);
}
/**
* 清理id映射关系
*
* @param id id
*/
private void clearMap(String id) {
this.resultValueMap.remove(id);
this.resultTypeMap.remove(id);
this.resultExceptionMap.remove(id);
}
public String addUri(String[] uris) {
List<String> uriList = Arrays.asList(uris);
return null;
}
@Override
public void onOpen(ServerHandshake serverHandshake) {
}
@Override
public void onMessage(String message) {
log.debug("onMessage : {}", 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) {
System.out.println("put exception");
String errorMessage = error.get("message").getAsString();
this.resultExceptionMap.put(id, new Aria2WebSocketClientException(errorMessage));
return;
}
Type resultType = this.resultTypeMap.get(id);
Aria2WebSocketResponse result = null;
try {
result = gson.fromJson(jsonElement, resultType);
} catch (Exception e) {
this.resultExceptionMap.put(id, new Aria2WebSocketClientException(e));
}
this.resultValueMap.put(id, result);
} catch (Exception e) {
this.resultExceptionMap.put(id, new Aria2WebSocketClientException(e));
}
}
@Override
@SneakyThrows
public void onClose(int code, String reason, boolean remote) {
this.reconnectBlocking();
}
@Override
public void onError(Exception ex) {
}
}

View File

@ -1,5 +1,6 @@
package cn.montaro.aria2.client.websocket; package cn.montaro.aria2.client.websocket;
import cn.montaro.aria2.Aria2Config;
import cn.montaro.aria2.annotation.Aria2Method; import cn.montaro.aria2.annotation.Aria2Method;
import cn.montaro.aria2.client.websocket.exception.Aria2WebSocketClientException; import cn.montaro.aria2.client.websocket.exception.Aria2WebSocketClientException;
import com.google.gson.*; import com.google.gson.*;
@ -26,10 +27,10 @@ public class Aria2WebSocketProxy implements InvocationHandler {
private final Gson gson; private final Gson gson;
private final WebSocketImpl webSocket; private final WebSocketImpl webSocket;
private final Aria2WebSocketConfig config; private final Aria2Config config;
@SneakyThrows @SneakyThrows
public Aria2WebSocketProxy(Aria2WebSocketConfig config) { public Aria2WebSocketProxy(Aria2Config config) {
this.config = config; this.config = config;
this.gson = new GsonBuilder().create(); this.gson = new GsonBuilder().create();
this.webSocket = new WebSocketImpl(config.getURI()); this.webSocket = new WebSocketImpl(config.getURI());
@ -40,8 +41,9 @@ public class Aria2WebSocketProxy implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Aria2Method aria2Method = method.getDeclaredAnnotation(Aria2Method.class); Aria2Method aria2Method = method.getDeclaredAnnotation(Aria2Method.class);
String methodName = aria2Method.value(); String methodName = aria2Method.value();
Type genericReturnType = method.getGenericReturnType();
Aria2WebSocketRequest request = this.buildRequest(methodName, args); Aria2WebSocketRequest request = this.buildRequest(methodName, args);
Object o = this.sendRequest(request, method.getGenericReturnType()); Object o = this.sendRequest(request, genericReturnType);
return o; return o;
} }
@ -153,7 +155,7 @@ public class Aria2WebSocketProxy implements InvocationHandler {
log.debug("receive message:{}", message); log.debug("receive message:{}", message);
JsonObject jsonObject = JsonParser.parseString(message).getAsJsonObject(); JsonObject jsonObject = JsonParser.parseString(message).getAsJsonObject();
JsonElement idObj = jsonObject.get("id"); JsonElement idObj = jsonObject.get("id");
if (idObj == null) { if (idObj == null || idObj instanceof JsonNull) {
return; return;
} }
String id = idObj.getAsString(); String id = idObj.getAsString();

View File

@ -15,10 +15,8 @@ import java.io.Serializable;
@Data @Data
@Accessors(chain = true) @Accessors(chain = true)
public class Aria2WebSocketRequest implements Serializable { public class Aria2WebSocketRequest implements Serializable {
private String id; private String id;
private String jsonrpc = "2.0"; private String jsonrpc = "2.0";
private String method; private String method;
private JsonElement params; private JsonElement params;
} }

View File

@ -1,18 +0,0 @@
package cn.montaro.aria2.client.websocket;
import lombok.Data;
/**
* Description:
*
* @author ZhangJiaYu
* @date 2021/12/14
*/
@Data
public class Aria2WebSocketResponse<T> {
private String id;
private String jsonrpc;
private T result;
}

View File

@ -1,57 +0,0 @@
package cn.montaro.aria2.client.websocket.param;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Description:
*
* @author ZhangJiaYu
* @date 2021/12/14
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AddUriParam extends Aria2Param {
/**
* 资源URI支持HTTP/FTP/SFTP/BitTorrent
*/
private List<String> uris = new ArrayList<>();
/**
* 下载选项 详情请看<a href="http://aria2.github.io/manual/en/html/aria2c.html#id3">文档</a>
*/
private Map<String, String> options = null;
/**
* 下载顺序如果是0则添加到开头
* <p>If position is given, it must be an integer starting from 0. The new download will be inserted at position in the waiting queue.</p>
* <p>If position is omitted or position is larger than the current size of the queue, the new download is appended to the end of the queue. </p>
*/
private Integer position;
public AddUriParam addUri(String uri) {
this.uris.add(uri);
return this;
}
public AddUriParam setOption(String name, String value) {
if (this.options == null) {
this.options = new HashMap<>();
}
this.options.put(name, value);
return this;
}
public void setPosition(Integer position) {
if (this.options == null) {
this.options = new HashMap<>();
}
this.position = position;
}
}

View File

@ -1,16 +0,0 @@
package cn.montaro.aria2.client.websocket.param;
import lombok.Data;
import java.io.Serializable;
/**
* Description:
*
* @author ZhangJiaYu
* @date 2021/12/14
*/
@Data
public class Aria2Param implements Serializable {
}

View File

@ -0,0 +1,22 @@
package cn.montaro.aria2.constants;
/**
* Description:
*
* @author ZhangJiaYu
* @date 2021/12/15
*/
public class Aria2Protocol {
public static class WebSocket {
public final static String WS = "ws";
public final static String WSS = "wss";
}
public static class Http {
public final static String HTTP = "http";
public final static String HTTPS = "https";
}
}

View File

@ -1,14 +0,0 @@
package cn.montaro.aria2.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";
}

View File

@ -0,0 +1,19 @@
import cn.montaro.aria2.Aria2Client;
import cn.montaro.aria2.Aria2ClientFactory;
import cn.montaro.aria2.Aria2Config;
import org.junit.Test;
public class Aria2ClientTest {
Aria2Config config = new Aria2Config()
.setHost("192.168.99.120")
.setSecret("montaro");
Aria2Client client = Aria2ClientFactory.httpClient(config);
@Test
public void test() {
String globalStat = client.getGlobalStat();
System.out.println("globalStat = " + globalStat);
}
}

View File

@ -1,67 +0,0 @@
import cn.montaro.aria2.Aria2Client;
import cn.montaro.aria2.Aria2ClientFactory;
import cn.montaro.aria2.client.websocket.Aria2WebSocketConfig;
import cn.montaro.aria2.client.websocket.Aria2WebSocketClient;
import com.sun.org.apache.xpath.internal.SourceTree;
import org.junit.Test;
import javax.lang.model.element.VariableElement;
import java.sql.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Description:
*
* @author ZhangJiaYu
* @date 2021/12/15
*/
public class Aria2WebSocketClientTest {
Aria2WebSocketConfig config = new Aria2WebSocketConfig()
.setHost("192.168.99.120")
.setSecret("montaro");
Aria2Client client = Aria2ClientFactory.webSocketClient(config);
@Test
public void tellActive() {
String s = client.tellActive("gid");
System.out.println(s);
}
@Test
public void tellWaiting() {
String s = client.tellWaiting(0, 1000, null);
System.out.println(s);
}
@Test
public void getGlobalStat() {
String globalStat = client.getGlobalStat();
System.out.println(globalStat);
}
@Test
public void changeUri() {
List<String> addUris = new ArrayList<String>();
addUris.add("https://mirrors.tuna.tsinghua.edu.cn/centos/8.5.2111/isos/x86_64/CentOS-8.5.2111-x86_64-dvd1.iso");
String result = client.changeUri("97d4d126a7263df8", 1, new ArrayList<String>(), addUris);
System.out.println(result);
}
@Test
public void tellStatus() {
String s = client.tellStatus("1bfe98b1bc6c47aa");
System.out.println("s = " + s);
}
@Test
public void addDownload() {
String magnet = "magnet:?xt=urn:btih:5e1464caced74be780397896d5a255a88b872542&tr=https%3A%2F%2Ftr.bangumi.moe%3A9696%2Fannounce&tr=http%3A%2F%2Ftr.bangumi.moe%3A6969%2Fannounce&tr=udp%3A%2F%2Ftr.bangumi.moe%3A6969%2Fannounce&tr=http%3A%2F%2Fopen.acgtracker.com%3A1096%2Fannounce&tr=http%3A%2F%2F208.67.16.113%3A8000%2Fannounce&tr=udp%3A%2F%2F208.67.16.113%3A8000%2Fannounce&tr=http%3A%2F%2Ftracker.ktxp.com%3A6868%2Fannounce&tr=http%3A%2F%2Ftracker.ktxp.com%3A7070%2Fannounce&tr=http%3A%2F%2Ft2.popgo.org%3A7456%2Fannonce&tr=http%3A%2F%2Fbt.sc-ol.com%3A2710%2Fannounce&tr=http%3A%2F%2Fshare.camoe.cn%3A8080%2Fannounce&tr=http%3A%2F%2F61.154.116.205%3A8000%2Fannounce&tr=http%3A%2F%2Fbt.rghost.net%3A80%2Fannounce&tr=http%3A%2F%2Ftracker.openbittorrent.com%3A80%2Fannounce&tr=http%3A%2F%2Ftracker.publicbt.com%3A80%2Fannounce&tr=http%3A%2F%2Ftracker.prq.to%2Fannounce&tr=http%3A%2F%2Fopen.nyaatorrents.info%3A6544%2Fannounce";
List<String> uris = new ArrayList<>();
uris.add(magnet);
String s = client.addUri(uris, null, null);
System.out.println(s);
}
}