From bc8427e6a012539ce236066defa2406dc8b0d1e7 Mon Sep 17 00:00:00 2001 From: tongtongstudio Date: Thu, 24 Apr 2025 19:10:55 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=98=BF=E9=87=8C=E4=BA=91?= =?UTF-8?q?=E6=8E=A8=E9=80=81=E5=92=8Cwebsocket?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 16 ++++ .../backend/config/WebSocketConfig.java | 13 ++++ .../backend/controller/HelloController.java | 7 ++ .../backend/controller/push/AsyncPush.java | 78 +++++++++++++++++++ .../backend/controller/push/SyncPush.java | 40 ++++++++++ .../backend/service/PushService.java | 46 +++++++++++ .../backend/service/WebSocketService.java | 67 ++++++++++++++++ 7 files changed, 267 insertions(+) create mode 100644 src/main/java/com/mir4updater/backend/config/WebSocketConfig.java create mode 100644 src/main/java/com/mir4updater/backend/controller/push/AsyncPush.java create mode 100644 src/main/java/com/mir4updater/backend/controller/push/SyncPush.java create mode 100644 src/main/java/com/mir4updater/backend/service/PushService.java create mode 100644 src/main/java/com/mir4updater/backend/service/WebSocketService.java 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