diff --git a/pom.xml b/pom.xml
index 80e5f23..ec4c145 100644
--- a/pom.xml
+++ b/pom.xml
@@ -84,6 +84,10 @@
org.springframework.boot
spring-boot-starter-cache
+
+ org.springframework.boot
+ spring-boot-starter-websocket
+
com.google.code.gson
gson
@@ -94,6 +98,18 @@
apk-parser
2.6.10
+
+
+ com.aliyun
+ alibabacloud-push20160801
+ 1.0.13
+
+
+
+ com.aliyun
+ push20160801
+ 1.0.17
+
diff --git a/src/main/java/com/mir4updater/backend/config/WebSocketConfig.java b/src/main/java/com/mir4updater/backend/config/WebSocketConfig.java
new file mode 100644
index 0000000..8043eef
--- /dev/null
+++ b/src/main/java/com/mir4updater/backend/config/WebSocketConfig.java
@@ -0,0 +1,13 @@
+package com.mir4updater.backend.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
+
+@Configuration
+public class WebSocketConfig {
+ @Bean
+ public ServerEndpointExporter serverEndpointExporter() {
+ return new ServerEndpointExporter();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/mir4updater/backend/controller/HelloController.java b/src/main/java/com/mir4updater/backend/controller/HelloController.java
index 9500c5f..808acd3 100644
--- a/src/main/java/com/mir4updater/backend/controller/HelloController.java
+++ b/src/main/java/com/mir4updater/backend/controller/HelloController.java
@@ -1,6 +1,7 @@
package com.mir4updater.backend.controller;
import com.mir4updater.backend.result.Result;
+import com.mir4updater.backend.service.WebSocketService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
@@ -42,4 +43,10 @@ public class HelloController {
String result = stringRedisTemplate.opsForValue().get("username");
return result;
}
+
+ @PostMapping("/web_send")
+ public String webSendMessage(@RequestParam(value = "message") String message) {
+ WebSocketService.sendMessageAll(message);
+ return "sendMessageAll";
+ }
}
diff --git a/src/main/java/com/mir4updater/backend/controller/push/AsyncPush.java b/src/main/java/com/mir4updater/backend/controller/push/AsyncPush.java
new file mode 100644
index 0000000..b24400c
--- /dev/null
+++ b/src/main/java/com/mir4updater/backend/controller/push/AsyncPush.java
@@ -0,0 +1,78 @@
+package com.mir4updater.backend.controller.push;
+
+import com.aliyun.auth.credentials.Credential;
+import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
+import com.aliyun.sdk.service.push20160801.AsyncClient;
+import com.aliyun.sdk.service.push20160801.models.BindAliasRequest;
+import com.aliyun.sdk.service.push20160801.models.BindAliasResponse;
+import com.google.gson.Gson;
+import darabonba.core.client.ClientOverrideConfiguration;
+
+import java.util.concurrent.CompletableFuture;
+
+public class AsyncPush {
+ public static void main(String[] args) throws Exception {
+
+ // HttpClient Configuration
+ /*HttpClient httpClient = new ApacheAsyncHttpClientBuilder()
+ .connectionTimeout(Duration.ofSeconds(10)) // Set the connection timeout time, the default is 10 seconds
+ .responseTimeout(Duration.ofSeconds(10)) // Set the response timeout time, the default is 20 seconds
+ .maxConnections(128) // Set the connection pool size
+ .maxIdleTimeOut(Duration.ofSeconds(50)) // Set the connection pool timeout, the default is 30 seconds
+ // Configure the proxy
+ .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("", 9001))
+ .setCredentials("", ""))
+ // If it is an https connection, you need to configure the certificate, or ignore the certificate(.ignoreSSL(true))
+ .x509TrustManagers(new X509TrustManager[]{})
+ .keyManagers(new KeyManager[]{})
+ .ignoreSSL(false)
+ .build();*/
+
+ // Configure Credentials authentication information, including ak, secret, token
+ StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
+ // Please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
+ .accessKeyId("335514186")
+ .accessKeySecret("dc39560b76c54c408ece7dce2f21464f")
+ //.securityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN")) // use STS token
+ .build());
+
+ // Configure the Client
+ AsyncClient client = AsyncClient.builder()
+ //.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
+ .credentialsProvider(provider)
+ //.serviceConfiguration(Configuration.create()) // Service-level configuration
+ // Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
+ .overrideConfiguration(
+ ClientOverrideConfiguration.create()
+ // Endpoint 请参考 https://api.aliyun.com/product/Push
+ .setEndpointOverride("cloudpush.aliyuncs.com")
+ //.setConnectTimeout(Duration.ofSeconds(30))
+ )
+ .build();
+
+ // Parameter settings for API request
+ BindAliasRequest bindAliasRequest = BindAliasRequest.builder()
+ .appKey(1L)
+ .deviceId("e0b4fb8ebeb44de5be3617f4a901b8f5")
+ // Request-level configuration rewrite, can set Http request parameters, etc.
+ // .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
+ .build();
+
+ // Asynchronously get the return value of the API request
+ CompletableFuture response = client.bindAlias(bindAliasRequest);
+ // Synchronously get the return value of the API request
+ BindAliasResponse resp = response.get();
+ System.out.println(new Gson().toJson(resp));
+ // Asynchronous processing of return values
+ /*response.thenAccept(resp -> {
+ System.out.println(new Gson().toJson(resp));
+ }).exceptionally(throwable -> { // Handling exceptions
+ System.out.println(throwable.getMessage());
+ return null;
+ });*/
+
+ // Finally, close the client
+ client.close();
+ }
+
+}
diff --git a/src/main/java/com/mir4updater/backend/controller/push/SyncPush.java b/src/main/java/com/mir4updater/backend/controller/push/SyncPush.java
new file mode 100644
index 0000000..e562a15
--- /dev/null
+++ b/src/main/java/com/mir4updater/backend/controller/push/SyncPush.java
@@ -0,0 +1,40 @@
+package com.mir4updater.backend.controller.push;
+
+import com.aliyun.push20160801.models.PushRequest;
+import com.aliyun.push20160801.models.PushResponse;
+import com.aliyun.teaopenapi.models.Config;
+
+public class SyncPush {
+
+ public static com.aliyun.push20160801.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
+ Config config = new Config();
+ // 您的AccessKey ID
+ config.accessKeyId = accessKeyId;
+ // 您的AccessKey Secret
+ config.accessKeySecret = accessKeySecret;
+ config.regionId = "cn-hangzhou";
+ return new com.aliyun.push20160801.Client(config);
+ }
+
+ public static void main(String[] args_) throws Exception {
+ com.aliyun.push20160801.Client client = createClient("LTAI5tBWFbkuKgcobdcqpFus",
+ "bYvEk0lgfvUzuA8NSlcSTKPkKy5Uow");
+ PushRequest request = new PushRequest()
+ .setAppKey(335514186L)
+ .setPushType("MESSAGE")
+ .setDeviceType("ANDROID")
+ .setStoreOffline(true)
+ .setIOSRemind(true)
+ .setAndroidRemind(true)
+ .setTarget("ALIAS")
+ .setTargetValue("e0b4fb8ebeb44de5be3617f4a901b8f5")
+ .setTitle("test")
+ .setBody("2")
+ .setIOSRemindBody("3")
+ .setAndroidPopupTitle("4")
+ .setAndroidPopupBody("5");
+ PushResponse response = client.push(request);
+ System.out.println(response.getStatusCode());
+ }
+
+}
diff --git a/src/main/java/com/mir4updater/backend/service/PushService.java b/src/main/java/com/mir4updater/backend/service/PushService.java
new file mode 100644
index 0000000..c254427
--- /dev/null
+++ b/src/main/java/com/mir4updater/backend/service/PushService.java
@@ -0,0 +1,46 @@
+package com.mir4updater.backend.service;
+
+import com.aliyun.push20160801.models.PushRequest;
+import com.aliyun.push20160801.models.PushResponse;
+import com.aliyun.teaopenapi.models.Config;
+import org.springframework.stereotype.Service;
+
+@Service
+public class PushService {
+
+ public static com.aliyun.push20160801.Client createClient() throws Exception {
+ Config config = new Config();
+ // 您的AccessKey ID
+ config.accessKeyId = "LTAI5tBWFbkuKgcobdcqpFus";
+ // 您的AccessKey Secret
+ config.accessKeySecret = "bYvEk0lgfvUzuA8NSlcSTKPkKy5Uow";
+ config.regionId = "cn-shenzhen";
+ return new com.aliyun.push20160801.Client(config);
+ }
+
+ public PushResponse pushUpdate(String uuid, String message) throws Exception {
+ PushRequest request = new PushRequest()
+ .setAppKey(335514186L)
+ .setPushType("MESSAGE")
+ .setDeviceType("ANDROID")
+ .setTarget("ALIAS")
+ .setTargetValue(uuid)
+ .setTitle("test")
+ .setBody("2");
+ PushResponse response = createClient().push(request);
+ return response;
+ }
+
+ public PushResponse pushAllDevices(String message) throws Exception {
+ PushRequest request = new PushRequest()
+ .setAppKey(335514186L)
+ .setPushType("MESSAGE")
+ .setDeviceType("ANDROID")
+ .setTarget("ALL")
+ .setTargetValue("ALL")
+ .setTitle("test")
+ .setBody("2");
+ PushResponse response = createClient().push(request);
+ return response;
+ }
+}
diff --git a/src/main/java/com/mir4updater/backend/service/WebSocketService.java b/src/main/java/com/mir4updater/backend/service/WebSocketService.java
new file mode 100644
index 0000000..dbfc52f
--- /dev/null
+++ b/src/main/java/com/mir4updater/backend/service/WebSocketService.java
@@ -0,0 +1,67 @@
+package com.mir4updater.backend.service;
+
+import jakarta.websocket.OnClose;
+import jakarta.websocket.OnMessage;
+import jakarta.websocket.OnOpen;
+import jakarta.websocket.Session;
+import jakarta.websocket.server.PathParam;
+import jakarta.websocket.server.ServerEndpoint;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.stereotype.Component;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Component
+@ServerEndpoint("/websocket/{terminalId}")
+public class WebSocketService {
+ private static final Map CLIENTS = new ConcurrentHashMap<>();
+
+ public static Logger logger = LogManager.getLogger(WebSocketService.class);
+
+ @OnOpen
+ public void onOpen(@PathParam("terminalId") String terminalId, Session session) {
+ if (CLIENTS.containsKey(terminalId)) {
+ try {
+ CLIENTS.get(terminalId).close();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ CLIENTS.put(terminalId, session);
+ logger.info(session.getId());
+ logger.info("终端 {} 已连接,当前在线数:{}", terminalId, CLIENTS.size());
+ }
+
+ @OnClose
+ public void onClose(@PathParam("terminalId") String terminalId, Session session) {
+ CLIENTS.remove(terminalId);
+ logger.info(session.getId());
+ logger.info("终端 {} 已断开", terminalId);
+ }
+
+ @OnMessage
+ public void onMessage(String message, Session session) {
+ logger.info(session.getId());
+ logger.info("收到消息:{}", message);
+ }
+
+ // 推送消息方法
+ public static void sendMessage(String terminalId, String message) {
+ Session session = CLIENTS.get(terminalId);
+ if (session != null && session.isOpen()) {
+ session.getAsyncRemote().sendText(message); // 异步发送避免阻塞
+ }
+ }
+
+ public static void sendMessageAll(String message) {
+ for (Map.Entry entry : CLIENTS.entrySet()) {
+ Session session = entry.getValue();
+ if (session != null && session.isOpen()) {
+ session.getAsyncRemote().sendText(message); // 异步发送避免阻塞
+ }
+ }
+ }
+}
\ No newline at end of file