From 17a7ef245544671e25ad3adf0e75cc94f0b67aba Mon Sep 17 00:00:00 2001 From: "DESKTOP-4U0TDEF\\20371" <2037158277@qq.com> Date: Mon, 19 Jul 2021 10:27:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86websocket=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E7=9A=84=E9=85=8D=E7=BD=AE=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 9 ++ .../java/com/xkrs/FirePointApplication.java | 3 + .../common/config/RestTemplateConfig.java | 91 +++++++++++++ .../config/WebSocketSecurityConfig.java | 25 ++++ src/main/java/com/xkrs/utils/Query.java | 2 +- .../config/WebSocketBrokerConfig.java | 25 ++++ .../websocket/config/WebSocketConfig.java | 16 +++ .../websocket/controller/TestController.java | 18 +++ .../websocket/WebSocketController.java | 24 ++++ .../websocketbroker/ViewController.java | 17 +++ .../WebSocketBrokerController.java | 21 +++ .../websocket/service/WebSocketServer.java | 128 ++++++++++++++++++ .../websocket/ClientServerMessage.java | 18 +++ .../websocket/ServerClientMessage.java | 21 +++ src/main/resources/application.properties | 2 + 15 files changed, 419 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/xkrs/common/config/RestTemplateConfig.java create mode 100644 src/main/java/com/xkrs/common/config/WebSocketSecurityConfig.java create mode 100644 src/main/java/com/xkrs/websocket/config/WebSocketBrokerConfig.java create mode 100644 src/main/java/com/xkrs/websocket/config/WebSocketConfig.java create mode 100644 src/main/java/com/xkrs/websocket/controller/TestController.java create mode 100644 src/main/java/com/xkrs/websocket/controller/websocket/WebSocketController.java create mode 100644 src/main/java/com/xkrs/websocket/controller/websocketbroker/ViewController.java create mode 100644 src/main/java/com/xkrs/websocket/controller/websocketbroker/WebSocketBrokerController.java create mode 100644 src/main/java/com/xkrs/websocket/service/WebSocketServer.java create mode 100644 src/main/java/com/xkrs/websocket/websocket/ClientServerMessage.java create mode 100644 src/main/java/com/xkrs/websocket/websocket/ServerClientMessage.java diff --git a/pom.xml b/pom.xml index 5df0585..007bdca 100644 --- a/pom.xml +++ b/pom.xml @@ -48,6 +48,15 @@ org.springframework.boot spring-boot-starter-security + + org.springframework.security + spring-security-messaging + + + org.springframework.boot + spring-boot-starter-websocket + provided + org.springframework.boot spring-boot-devtools diff --git a/src/main/java/com/xkrs/FirePointApplication.java b/src/main/java/com/xkrs/FirePointApplication.java index 3222b01..8de176b 100644 --- a/src/main/java/com/xkrs/FirePointApplication.java +++ b/src/main/java/com/xkrs/FirePointApplication.java @@ -3,6 +3,9 @@ package com.xkrs; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +/** + * @author XinYi Song + */ @SpringBootApplication public class FirePointApplication { diff --git a/src/main/java/com/xkrs/common/config/RestTemplateConfig.java b/src/main/java/com/xkrs/common/config/RestTemplateConfig.java new file mode 100644 index 0000000..93eb92b --- /dev/null +++ b/src/main/java/com/xkrs/common/config/RestTemplateConfig.java @@ -0,0 +1,91 @@ +package com.xkrs.common.config; + +/** + * @author xkrs + */ +import org.apache.http.client.HttpClient; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.ssl.SSLContextBuilder; +import org.apache.http.ssl.TrustStrategy; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.web.client.DefaultResponseErrorHandler; +import org.springframework.web.client.RestTemplate; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.SSLContext; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +/** + * @Author: HongZhi Wang + * @Date: 2020/8/17 16:45 + * + * 创建RestTemplate配置类,设置连接池大小、超时时间、重试机制等。 + */ +@Configuration +public class RestTemplateConfig { + + @Bean + public RestTemplate restTemplate(){ + RestTemplate restTemplate = new RestTemplate(); + restTemplate.setRequestFactory(clientHttpRequestFactory()); + restTemplate.setErrorHandler(new DefaultResponseErrorHandler()); + return restTemplate; + } + + @Bean + public HttpComponentsClientHttpRequestFactory clientHttpRequestFactory() { + try { + HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); + SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { + @Override + public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { + return true; + } + }).build(); + httpClientBuilder.setSSLContext(sslContext); + HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE; + SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier); + Registry socketFactoryRegistry = RegistryBuilder.create() + .register("http", PlainConnectionSocketFactory.getSocketFactory()) + //注册http和https请求 + .register("https", sslConnectionSocketFactory).build(); + //开始设置连接池 + //创建连接池 + PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); + // 最大连接数500 + poolingHttpClientConnectionManager.setMaxTotal(500); + // 同路由并发数100 + poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100); + httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager); + // 重试次数 + httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true)); + HttpClient httpClient = httpClientBuilder.build(); + // httpClient连接配置 + HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); + // 连接超时 + clientHttpRequestFactory.setConnectTimeout(20000); + // 数据读取超时时间 + clientHttpRequestFactory.setReadTimeout(30000); + // 连接不够用的等待时间 + clientHttpRequestFactory.setConnectionRequestTimeout(20000); + return clientHttpRequestFactory; + } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) { + System.out.println("初始化HTTP连接池出错"+ e); + } + return null; + } +} diff --git a/src/main/java/com/xkrs/common/config/WebSocketSecurityConfig.java b/src/main/java/com/xkrs/common/config/WebSocketSecurityConfig.java new file mode 100644 index 0000000..5ea9f85 --- /dev/null +++ b/src/main/java/com/xkrs/common/config/WebSocketSecurityConfig.java @@ -0,0 +1,25 @@ +package com.xkrs.common.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry; +import org.springframework.security.config.annotation.web.socket.AbstractSecurityWebSocketMessageBrokerConfigurer; + +import static org.springframework.messaging.simp.SimpMessageType.MESSAGE; +import static org.springframework.messaging.simp.SimpMessageType.SUBSCRIBE; + + +/** + * @author xkrs + */ +@Configuration +public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer { + @Override + protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) { + messages + .nullDestMatcher().authenticated() + .simpSubscribeDestMatchers("/user/queue/errors").permitAll() + .simpTypeMatchers(MESSAGE, SUBSCRIBE).denyAll() + .anyMessage().denyAll(); + + } +} \ No newline at end of file diff --git a/src/main/java/com/xkrs/utils/Query.java b/src/main/java/com/xkrs/utils/Query.java index 032aa3c..ec382e7 100644 --- a/src/main/java/com/xkrs/utils/Query.java +++ b/src/main/java/com/xkrs/utils/Query.java @@ -57,7 +57,7 @@ public class Query { } /** - * 查询近3天的火点 + * 查询近一周的火点 * @param startTime * @param endTime * @return diff --git a/src/main/java/com/xkrs/websocket/config/WebSocketBrokerConfig.java b/src/main/java/com/xkrs/websocket/config/WebSocketBrokerConfig.java new file mode 100644 index 0000000..bb8d377 --- /dev/null +++ b/src/main/java/com/xkrs/websocket/config/WebSocketBrokerConfig.java @@ -0,0 +1,25 @@ +package com.xkrs.websocket.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +/** + * websocket广播配置 + * @author xkrs + */ +@Configuration +@EnableWebSocketMessageBroker +public class WebSocketBrokerConfig implements WebSocketMessageBrokerConfigurer { + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/endPointClientServer").withSockJS(); + } + + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + registry.enableSimpleBroker("/ws"); + } +} diff --git a/src/main/java/com/xkrs/websocket/config/WebSocketConfig.java b/src/main/java/com/xkrs/websocket/config/WebSocketConfig.java new file mode 100644 index 0000000..261844d --- /dev/null +++ b/src/main/java/com/xkrs/websocket/config/WebSocketConfig.java @@ -0,0 +1,16 @@ +package com.xkrs.websocket.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * @author xkrs + */ +@Configuration +public class WebSocketConfig { + @Bean + public ServerEndpointExporter serverEndpointExporter(){ + return new ServerEndpointExporter(); + } +} diff --git a/src/main/java/com/xkrs/websocket/controller/TestController.java b/src/main/java/com/xkrs/websocket/controller/TestController.java new file mode 100644 index 0000000..aad8385 --- /dev/null +++ b/src/main/java/com/xkrs/websocket/controller/TestController.java @@ -0,0 +1,18 @@ +package com.xkrs.websocket.controller; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author xkrs + */ +@RestController +@RequestMapping("/test") +public class TestController { + + @GetMapping("/hello") + public String sayHello(){ + return "asdasd"; + } +} diff --git a/src/main/java/com/xkrs/websocket/controller/websocket/WebSocketController.java b/src/main/java/com/xkrs/websocket/controller/websocket/WebSocketController.java new file mode 100644 index 0000000..d9e689a --- /dev/null +++ b/src/main/java/com/xkrs/websocket/controller/websocket/WebSocketController.java @@ -0,0 +1,24 @@ +package com.xkrs.websocket.controller.websocket; + +import com.xkrs.websocket.service.WebSocketServer; +import org.springframework.web.bind.annotation.*; + +/** + * @author xkrs + */ +@RestController +@RequestMapping("/api/socket") +public class WebSocketController { + + @GetMapping("/sendAll") + public String sendAll(@RequestParam String msg) { + WebSocketServer.broadInfo(msg); + return "success"; + } + + @RequestMapping(value = "/sendOne", method = RequestMethod.GET) + public String sendOne(@RequestParam String msg, @RequestParam String session) { + WebSocketServer.sendMsg(msg, session); + return "success"; + } +} diff --git a/src/main/java/com/xkrs/websocket/controller/websocketbroker/ViewController.java b/src/main/java/com/xkrs/websocket/controller/websocketbroker/ViewController.java new file mode 100644 index 0000000..4bd39b1 --- /dev/null +++ b/src/main/java/com/xkrs/websocket/controller/websocketbroker/ViewController.java @@ -0,0 +1,17 @@ +package com.xkrs.websocket.controller.websocketbroker; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; + +/** + * @author xkrs + */ +@Configuration +public class ViewController extends WebMvcConfigurerAdapter { + + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/ws").setViewName("/ws"); + } +} diff --git a/src/main/java/com/xkrs/websocket/controller/websocketbroker/WebSocketBrokerController.java b/src/main/java/com/xkrs/websocket/controller/websocketbroker/WebSocketBrokerController.java new file mode 100644 index 0000000..9700d44 --- /dev/null +++ b/src/main/java/com/xkrs/websocket/controller/websocketbroker/WebSocketBrokerController.java @@ -0,0 +1,21 @@ +package com.xkrs.websocket.controller.websocketbroker; + +import com.xkrs.websocket.websocket.ClientServerMessage; +import com.xkrs.websocket.websocket.ServerClientMessage; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.SendTo; +import org.springframework.stereotype.Controller; + +/** + * @author xkrs + */ +@Controller +public class WebSocketBrokerController { + + @MessageMapping("/hello") + @SendTo("/ws/getResponse") + public ServerClientMessage say(ClientServerMessage message) throws InterruptedException { + Thread.sleep(3000); + return new ServerClientMessage("hello," + message.getName() + "!"); + } +} diff --git a/src/main/java/com/xkrs/websocket/service/WebSocketServer.java b/src/main/java/com/xkrs/websocket/service/WebSocketServer.java new file mode 100644 index 0000000..c8a3685 --- /dev/null +++ b/src/main/java/com/xkrs/websocket/service/WebSocketServer.java @@ -0,0 +1,128 @@ +package com.xkrs.websocket.service; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.websocket.*; +import javax.websocket.server.ServerEndpoint; +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.CopyOnWriteArraySet; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * @author xkrs + */ +@Component +@ServerEndpoint(value = "/ws/asset") +public class WebSocketServer { + + @PostConstruct + public void init() { + System.out.println("websocketBroker loading......"); + } + + private static Logger log = LoggerFactory.getLogger(WebSocketServer.class); + private static final AtomicInteger ONLINE_COUNT = new AtomicInteger(0); + private static CopyOnWriteArraySet sessionSet = new CopyOnWriteArraySet<>(); + + /** + * 连接建立 + */ + @OnOpen + public void onOpen(Session session) { + sessionSet.add(session); + //在线加1 + int cnt = ONLINE_COUNT.incrementAndGet(); + //log.info("have a new connect:{}", cnt); + //sendMsg(session, "connect success"); + } + + /** + * 连接关闭 + * + * @param session + */ + @OnClose + public void onClose(Session session) { + sessionSet.remove(session); + //在线减1 + int cnt = ONLINE_COUNT.decrementAndGet(); + log.info("have a connect close:{}", cnt); + } + + /** + * 收到客户端消息后调用的方法 + * + * @param session + * @param msg + */ + @OnMessage + public void onMessage(String msg, Session session) { + log.info("receive the msg:{}", msg); + } + + private static void sendMsg(Session session, String msg) { + try { + session.getBasicRemote().sendText(String.format(msg)); + } catch (IOException e) { + log.error("发送信息出错:{}", e.getMessage()); + e.printStackTrace(); + } + } + + private static void sendDate(Session session, Map map) { + try { + session.getBasicRemote().sendObject(map); + } catch (IOException | EncodeException e) { + log.error("发送信息出错:{}", e.getMessage()); + e.printStackTrace(); + } + } + + /** + * 指定session发送 + */ + public static void sendMsg(String msg, String sessionId) { + Session session = null; + for (Session s : sessionSet) { + if (s.getId().equals(sessionId)) { + session = s; + break; + } + } + if (session != null) { + sendMsg(session, msg); + } else { + log.warn("not find your session"); + } + } + + /** + * 群发消息 + */ + public static void broadInfo(String msg) { + for (Session s : sessionSet) { + synchronized (sessionSet){ + if (s.isOpen()) { + sendMsg(s, msg); + } + } + } + } + + /** + * 群发map消息 + * @param map + */ + public static void broadInfoMap(Map map) { + for (Session s : sessionSet) { + if (s.isOpen()) { + sendDate(s, map); + } + } + } + +} diff --git a/src/main/java/com/xkrs/websocket/websocket/ClientServerMessage.java b/src/main/java/com/xkrs/websocket/websocket/ClientServerMessage.java new file mode 100644 index 0000000..11c054e --- /dev/null +++ b/src/main/java/com/xkrs/websocket/websocket/ClientServerMessage.java @@ -0,0 +1,18 @@ +package com.xkrs.websocket.websocket; + +/** + * @author xkrs + */ +public class ClientServerMessage { + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + private String name; + +} diff --git a/src/main/java/com/xkrs/websocket/websocket/ServerClientMessage.java b/src/main/java/com/xkrs/websocket/websocket/ServerClientMessage.java new file mode 100644 index 0000000..b803856 --- /dev/null +++ b/src/main/java/com/xkrs/websocket/websocket/ServerClientMessage.java @@ -0,0 +1,21 @@ +package com.xkrs.websocket.websocket; + +/** + * @author xkrs + */ +public class ServerClientMessage { + + public String getResponseMsg() { + return responseMsg; + } + + public void setResponseMsg(String responseMsg) { + this.responseMsg = responseMsg; + } + + private String responseMsg; + + public ServerClientMessage(String responseMsg) { + this.responseMsg = responseMsg; + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 5d80227..238054a 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -47,6 +47,8 @@ spring.servlet.multipart.max-file-size = 64MB # 最大请求大小 spring.servlet.multipart.max-request-size = 70MB +spring.main.allow-bean-definition-overriding = true + # Geoserver服务器地址 my.GeoserverAdress = http://139.199.98.175:9080/geoserver/