From 7d1a310fe1b0f744de03248794b278f21426e7cd Mon Sep 17 00:00:00 2001 From: "Yangkai.Shen" <237497819@qq.com> Date: Sat, 15 Dec 2018 20:54:21 +0800 Subject: [PATCH] =?UTF-8?q?:tada:=20spring-boot-demo-websocket=20=E5=9F=BA?= =?UTF-8?q?=E6=9C=AC=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../websocket/common/WebSocketConsts.java | 18 + .../websocket/config/WebSocketConfig.java | 43 ++ .../com/xkcoding/websocket/model/Server.java | 220 ++++++++ .../xkcoding/websocket/model/server/Cpu.java | 101 ++++ .../xkcoding/websocket/model/server/Jvm.java | 133 +++++ .../xkcoding/websocket/model/server/Mem.java | 61 +++ .../xkcoding/websocket/model/server/Sys.java | 81 +++ .../websocket/model/server/SysFile.java | 107 ++++ .../com/xkcoding/websocket/payload/KV.java | 33 ++ .../xkcoding/websocket/payload/ServerVO.java | 39 ++ .../websocket/payload/server/CpuVO.java | 37 ++ .../websocket/payload/server/JvmVO.java | 39 ++ .../websocket/payload/server/MemVO.java | 34 ++ .../websocket/payload/server/SysFileVO.java | 44 ++ .../websocket/payload/server/SysVO.java | 36 ++ .../xkcoding/websocket/task/ServerTask.java | 49 ++ .../com/xkcoding/websocket/util/IpUtil.java | 169 ++++++ .../main/resources/static/js/sockjs.min.js | 27 + .../src/main/resources/static/js/stomp.js | 501 ++++++++++++++++++ .../src/main/resources/static/server.html | 97 ++++ 20 files changed, 1869 insertions(+) create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/common/WebSocketConsts.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/config/WebSocketConfig.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/Server.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/Cpu.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/Jvm.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/Mem.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/Sys.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/SysFile.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/payload/KV.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/payload/ServerVO.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/payload/server/CpuVO.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/payload/server/JvmVO.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/payload/server/MemVO.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/payload/server/SysFileVO.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/payload/server/SysVO.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/task/ServerTask.java create mode 100644 spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/util/IpUtil.java create mode 100644 spring-boot-demo-websocket/src/main/resources/static/js/sockjs.min.js create mode 100644 spring-boot-demo-websocket/src/main/resources/static/js/stomp.js create mode 100644 spring-boot-demo-websocket/src/main/resources/static/server.html diff --git a/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/common/WebSocketConsts.java b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/common/WebSocketConsts.java new file mode 100644 index 0000000..8b577e2 --- /dev/null +++ b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/common/WebSocketConsts.java @@ -0,0 +1,18 @@ +package com.xkcoding.websocket.common; + +/** + *
+ * WebSocket常量 + *
+ * + * @package: com.xkcoding.websocket.common + * @description: WebSocket常量 + * @author: yangkai.shen + * @date: Created in 2018-12-14 16:01 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +public interface WebSocketConsts { + String PUSH_SERVER = "/topic/server"; +} diff --git a/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/config/WebSocketConfig.java b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/config/WebSocketConfig.java new file mode 100644 index 0000000..47de6d4 --- /dev/null +++ b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/config/WebSocketConfig.java @@ -0,0 +1,43 @@ +package com.xkcoding.websocket.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +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配置 + *
+ * + * @package: com.xkcoding.websocket.config + * @description: WebSocket配置 + * @author: yangkai.shen + * @date: Created in 2018-12-14 15:58 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +@Configuration +@EnableWebSocket +@EnableWebSocketMessageBroker +public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + // 注册一个 /notification 端点,前端通过这个端点进行连接 + registry.addEndpoint("/notification") + //解决跨域问题 + .setAllowedOrigins("*") + .withSockJS(); + } + + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + //定义了一个客户端订阅地址的前缀信息,也就是客户端接收服务端发送消息的前缀信息 + registry.enableSimpleBroker("/topic"); + } + +} diff --git a/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/Server.java b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/Server.java new file mode 100644 index 0000000..8d51a73 --- /dev/null +++ b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/Server.java @@ -0,0 +1,220 @@ +package com.xkcoding.websocket.model; + +import cn.hutool.core.util.NumberUtil; +import com.xkcoding.websocket.model.server.*; +import com.xkcoding.websocket.util.IpUtil; +import oshi.SystemInfo; +import oshi.hardware.CentralProcessor; +import oshi.hardware.CentralProcessor.TickType; +import oshi.hardware.GlobalMemory; +import oshi.hardware.HardwareAbstractionLayer; +import oshi.software.os.FileSystem; +import oshi.software.os.OSFileStore; +import oshi.software.os.OperatingSystem; +import oshi.util.Util; + +import java.net.UnknownHostException; +import java.util.LinkedList; +import java.util.List; +import java.util.Properties; + +/** + *+ * 服务器相关信息实体 + *
+ * + * @package: com.xkcoding.websocket.model + * @description: 服务器相关信息实体 + * @author: yangkai.shen + * @date: Created in 2018-12-14 16:09 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +public class Server { + + private static final int OSHI_WAIT_SECOND = 1000; + + /** + * CPU相关信息 + */ + private Cpu cpu = new Cpu(); + + /** + * 內存相关信息 + */ + private Mem mem = new Mem(); + + /** + * JVM相关信息 + */ + private Jvm jvm = new Jvm(); + + /** + * 服务器相关信息 + */ + private Sys sys = new Sys(); + + /** + * 磁盘相关信息 + */ + private List+ * CPU相关信息实体 + *
+ * + * @package: com.xkcoding.websocket.model.server + * @description: CPU相关信息实体 + * @author: yangkai.shen + * @date: Created in 2018-12-14 16:09 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +public class Cpu { + /** + * 核心数 + */ + private int cpuNum; + + /** + * CPU总的使用率 + */ + private double total; + + /** + * CPU系统使用率 + */ + private double sys; + + /** + * CPU用户使用率 + */ + private double used; + + /** + * CPU当前等待率 + */ + private double wait; + + /** + * CPU当前空闲率 + */ + private double free; + + public int getCpuNum() { + return cpuNum; + } + + public void setCpuNum(int cpuNum) { + this.cpuNum = cpuNum; + } + + public double getTotal() { + return NumberUtil.round(NumberUtil.mul(total, 100), 2) + .doubleValue(); + } + + public void setTotal(double total) { + this.total = total; + } + + public double getSys() { + return NumberUtil.round(NumberUtil.mul(sys / total, 100), 2) + .doubleValue(); + } + + public void setSys(double sys) { + this.sys = sys; + } + + public double getUsed() { + return NumberUtil.round(NumberUtil.mul(used / total, 100), 2) + .doubleValue(); + } + + public void setUsed(double used) { + this.used = used; + } + + public double getWait() { + return NumberUtil.round(NumberUtil.mul(wait / total, 100), 2) + .doubleValue(); + } + + public void setWait(double wait) { + this.wait = wait; + } + + public double getFree() { + return NumberUtil.round(NumberUtil.mul(free / total, 100), 2) + .doubleValue(); + } + + public void setFree(double free) { + this.free = free; + } +} \ No newline at end of file diff --git a/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/Jvm.java b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/Jvm.java new file mode 100644 index 0000000..a0b770b --- /dev/null +++ b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/Jvm.java @@ -0,0 +1,133 @@ +package com.xkcoding.websocket.model.server; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.NumberUtil; + +import java.lang.management.ManagementFactory; +import java.util.Date; + +/** + *+ * JVM相关信息实体 + *
+ * + * @package: com.xkcoding.websocket.model.server + * @description: JVM相关信息实体 + * @author: yangkai.shen + * @date: Created in 2018-12-14 16:09 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +public class Jvm { + /** + * 当前JVM占用的内存总数(M) + */ + private double total; + + /** + * JVM最大可用内存总数(M) + */ + private double max; + + /** + * JVM空闲内存(M) + */ + private double free; + + /** + * JDK版本 + */ + private String version; + + /** + * JDK路径 + */ + private String home; + + /** + * JDK启动时间 + */ + private String startTime; + + /** + * JDK运行时间 + */ + private String runTime; + + public double getTotal() { + return NumberUtil.div(total, (1024 * 1024), 2); + } + + public void setTotal(double total) { + this.total = total; + } + + public double getMax() { + return NumberUtil.div(max, (1024 * 1024), 2); + } + + public void setMax(double max) { + this.max = max; + } + + public double getFree() { + return NumberUtil.div(free, (1024 * 1024), 2); + } + + public void setFree(double free) { + this.free = free; + } + + public double getUsed() { + return NumberUtil.div(total - free, (1024 * 1024), 2); + } + + public double getUsage() { + return NumberUtil.mul(NumberUtil.div(total - free, total, 4), 100); + } + + /** + * 获取JDK名称 + */ + public String getName() { + return ManagementFactory.getRuntimeMXBean() + .getVmName(); + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getHome() { + return home; + } + + public void setHome(String home) { + this.home = home; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getStartTime() { + return DateUtil.formatDateTime(new Date(ManagementFactory.getRuntimeMXBean() + .getStartTime())); + } + + + public void setRunTime(String runTime) { + this.runTime = runTime; + } + + public String getRunTime() { + long startTime = ManagementFactory.getRuntimeMXBean() + .getStartTime(); + return DateUtil.formatBetween(DateUtil.current(false) - startTime); + } +} \ No newline at end of file diff --git a/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/Mem.java b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/Mem.java new file mode 100644 index 0000000..0b72bf4 --- /dev/null +++ b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/Mem.java @@ -0,0 +1,61 @@ +package com.xkcoding.websocket.model.server; + +import cn.hutool.core.util.NumberUtil; + +/** + *+ * 內存相关信息实体 + *
+ * + * @package: com.xkcoding.websocket.model.server + * @description: 內存相关信息实体 + * @author: yangkai.shen + * @date: Created in 2018-12-14 16:09 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +public class Mem { + /** + * 内存总量 + */ + private double total; + + /** + * 已用内存 + */ + private double used; + + /** + * 剩余内存 + */ + private double free; + + public double getTotal() { + return NumberUtil.div(total, (1024 * 1024 * 1024), 2); + } + + public void setTotal(long total) { + this.total = total; + } + + public double getUsed() { + return NumberUtil.div(used, (1024 * 1024 * 1024), 2); + } + + public void setUsed(long used) { + this.used = used; + } + + public double getFree() { + return NumberUtil.div(free, (1024 * 1024 * 1024), 2); + } + + public void setFree(long free) { + this.free = free; + } + + public double getUsage() { + return NumberUtil.mul(NumberUtil.div(used, total, 4), 100); + } +} \ No newline at end of file diff --git a/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/Sys.java b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/Sys.java new file mode 100644 index 0000000..f2321cb --- /dev/null +++ b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/Sys.java @@ -0,0 +1,81 @@ +package com.xkcoding.websocket.model.server; + +/** + *+ * 系统相关信息实体 + *
+ * + * @package: com.xkcoding.websocket.model.server + * @description: 系统相关信息实体 + * @author: yangkai.shen + * @date: Created in 2018-12-14 16:10 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +public class Sys { + /** + * 服务器名称 + */ + private String computerName; + + /** + * 服务器Ip + */ + private String computerIp; + + /** + * 项目路径 + */ + private String userDir; + + /** + * 操作系统 + */ + private String osName; + + /** + * 系统架构 + */ + private String osArch; + + public String getComputerName() { + return computerName; + } + + public void setComputerName(String computerName) { + this.computerName = computerName; + } + + public String getComputerIp() { + return computerIp; + } + + public void setComputerIp(String computerIp) { + this.computerIp = computerIp; + } + + public String getUserDir() { + return userDir; + } + + public void setUserDir(String userDir) { + this.userDir = userDir; + } + + public String getOsName() { + return osName; + } + + public void setOsName(String osName) { + this.osName = osName; + } + + public String getOsArch() { + return osArch; + } + + public void setOsArch(String osArch) { + this.osArch = osArch; + } +} \ No newline at end of file diff --git a/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/SysFile.java b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/SysFile.java new file mode 100644 index 0000000..823cf75 --- /dev/null +++ b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/model/server/SysFile.java @@ -0,0 +1,107 @@ +package com.xkcoding.websocket.model.server; + +/** + *+ * 系统文件相关信息实体 + *
+ * + * @package: com.xkcoding.websocket.model.server + * @description: 系统文件相关信息实体 + * @author: yangkai.shen + * @date: Created in 2018-12-14 16:10 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +public class SysFile { + /** + * 盘符路径 + */ + private String dirName; + + /** + * 盘符类型 + */ + private String sysTypeName; + + /** + * 文件类型 + */ + private String typeName; + + /** + * 总大小 + */ + private String total; + + /** + * 剩余大小 + */ + private String free; + + /** + * 已经使用量 + */ + private String used; + + /** + * 资源的使用率 + */ + private double usage; + + public String getDirName() { + return dirName; + } + + public void setDirName(String dirName) { + this.dirName = dirName; + } + + public String getSysTypeName() { + return sysTypeName; + } + + public void setSysTypeName(String sysTypeName) { + this.sysTypeName = sysTypeName; + } + + public String getTypeName() { + return typeName; + } + + public void setTypeName(String typeName) { + this.typeName = typeName; + } + + public String getTotal() { + return total; + } + + public void setTotal(String total) { + this.total = total; + } + + public String getFree() { + return free; + } + + public void setFree(String free) { + this.free = free; + } + + public String getUsed() { + return used; + } + + public void setUsed(String used) { + this.used = used; + } + + public double getUsage() { + return usage; + } + + public void setUsage(double usage) { + this.usage = usage; + } +} \ No newline at end of file diff --git a/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/payload/KV.java b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/payload/KV.java new file mode 100644 index 0000000..2db7086 --- /dev/null +++ b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/payload/KV.java @@ -0,0 +1,33 @@ +package com.xkcoding.websocket.payload; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + *+ * 键值匹配 + *
+ * + * @package: com.xkcoding.websocket.payload + * @description: 键值匹配 + * @author: yangkai.shen + * @date: Created in 2018-12-14 17:41 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class KV { + /** + * 键 + */ + private String key; + + /** + * 值 + */ + private Object value; +} diff --git a/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/payload/ServerVO.java b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/payload/ServerVO.java new file mode 100644 index 0000000..d36b38a --- /dev/null +++ b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/payload/ServerVO.java @@ -0,0 +1,39 @@ +package com.xkcoding.websocket.payload; + +import com.google.common.collect.Lists; +import com.xkcoding.websocket.model.Server; +import com.xkcoding.websocket.payload.server.*; +import lombok.Data; + +import java.util.List; + +/** + *+ * 服务器信息VO + *
+ * + * @package: com.xkcoding.websocket.payload + * @description: 服务器信息VO + * @author: yangkai.shen + * @date: Created in 2018-12-14 17:25 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +@Data +public class ServerVO { + List+ * CPU相关信息实体VO + *
+ * + * @package: com.xkcoding.websocket.payload.server + * @description: CPU相关信息实体VO + * @author: yangkai.shen + * @date: Created in 2018-12-14 17:27 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +@Data +public class CpuVO { + List+ * JVM相关信息实体VO + *
+ * + * @package: com.xkcoding.websocket.payload.server + * @description: JVM相关信息实体VO + * @author: yangkai.shen + * @date: Created in 2018-12-14 17:28 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +@Data +public class JvmVO { + List+ * 內存相关信息实体VO + *
+ * + * @package: com.xkcoding.websocket.payload.server + * @description: 內存相关信息实体VO + * @author: yangkai.shen + * @date: Created in 2018-12-14 17:28 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +@Data +public class MemVO { + List+ * 系统文件相关信息实体VO + *
+ * + * @package: com.xkcoding.websocket.payload.server + * @description: 系统文件相关信息实体VO + * @author: yangkai.shen + * @date: Created in 2018-12-14 17:30 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +@Data +public class SysFileVO { + List+ * 系统相关信息实体VO + *
+ * + * @package: com.xkcoding.websocket.payload.server + * @description: 系统相关信息实体VO + * @author: yangkai.shen + * @date: Created in 2018-12-14 17:28 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +@Data +public class SysVO { + List+ * 服务器定时推送任务 + *
+ * + * @package: com.xkcoding.websocket.task + * @description: 服务器定时推送任务 + * @author: yangkai.shen + * @date: Created in 2018-12-14 16:04 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +@Slf4j +@Component +public class ServerTask { + @Autowired + private SimpMessagingTemplate wsTemplate; + + /** + * 按照标准时间来算,每隔 10s 执行一次 + */ + @Scheduled(cron = "0/10 * * * * ?") + public void websocket() throws Exception { + log.info("【推送消息】开始执行:{}", DateUtil.formatDateTime(new Date())); + // 查询服务器状态 + Server server = new Server(); + server.copyTo(); + ServerVO serverVO = new ServerVO(); + serverVO.create(server); + wsTemplate.convertAndSend(WebSocketConsts.PUSH_SERVER, JSONUtil.toJsonStr(serverVO)); + log.info("【推送消息】执行结束:{}", DateUtil.formatDateTime(new Date())); + } +} diff --git a/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/util/IpUtil.java b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/util/IpUtil.java new file mode 100644 index 0000000..68ac0c5 --- /dev/null +++ b/spring-boot-demo-websocket/src/main/java/com/xkcoding/websocket/util/IpUtil.java @@ -0,0 +1,169 @@ +package com.xkcoding.websocket.util; + +import javax.servlet.http.HttpServletRequest; +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + *+ * IP 工具类 + *
+ * + * @package: com.xkcoding.websocket.util + * @description: IP 工具类 + * @author: yangkai.shen + * @date: Created in 2018-12-14 16:08 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: yangkai.shen + */ +public class IpUtil { + public static String getIpAddr(HttpServletRequest request) { + if (request == null) { + return "unknown"; + } + String ip = request.getHeader("x-forwarded-for"); + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Forwarded-For"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getHeader("X-Real-IP"); + } + + if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + + return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip; + } + + public static boolean internalIp(String ip) { + byte[] addr = textToNumericFormatV4(ip); + return internalIp(addr) || "127.0.0.1".equals(ip); + } + + private static boolean internalIp(byte[] addr) { + final byte b0 = addr[0]; + final byte b1 = addr[1]; + // 10.x.x.x/8 + final byte SECTION_1 = 0x0A; + // 172.16.x.x/12 + final byte SECTION_2 = (byte) 0xAC; + final byte SECTION_3 = (byte) 0x10; + final byte SECTION_4 = (byte) 0x1F; + // 192.168.x.x/16 + final byte SECTION_5 = (byte) 0xC0; + final byte SECTION_6 = (byte) 0xA8; + switch (b0) { + case SECTION_1: + return true; + case SECTION_2: + if (b1 >= SECTION_3 && b1 <= SECTION_4) { + return true; + } + case SECTION_5: + switch (b1) { + case SECTION_6: + return true; + } + default: + return false; + } + } + + /** + * 将IPv4地址转换成字节 + * + * @param text IPv4地址 + * @return byte 字节 + */ + public static byte[] textToNumericFormatV4(String text) { + if (text.length() == 0) { + return null; + } + + byte[] bytes = new byte[4]; + String[] elements = text.split("\\.", -1); + try { + long l; + int i; + switch (elements.length) { + case 1: + l = Long.parseLong(elements[0]); + if ((l < 0L) || (l > 4294967295L)) { + return null; + } + bytes[0] = (byte) (int) (l >> 24 & 0xFF); + bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 2: + l = Integer.parseInt(elements[0]); + if ((l < 0L) || (l > 255L)) { + return null; + } + bytes[0] = (byte) (int) (l & 0xFF); + l = Integer.parseInt(elements[1]); + if ((l < 0L) || (l > 16777215L)) { + return null; + } + bytes[1] = (byte) (int) (l >> 16 & 0xFF); + bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 3: + for (i = 0; i < 2; ++i) { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + l = Integer.parseInt(elements[2]); + if ((l < 0L) || (l > 65535L)) { + return null; + } + bytes[2] = (byte) (int) (l >> 8 & 0xFF); + bytes[3] = (byte) (int) (l & 0xFF); + break; + case 4: + for (i = 0; i < 4; ++i) { + l = Integer.parseInt(elements[i]); + if ((l < 0L) || (l > 255L)) { + return null; + } + bytes[i] = (byte) (int) (l & 0xFF); + } + break; + default: + return null; + } + } catch (NumberFormatException e) { + return null; + } + return bytes; + } + + public static String getHostIp() { + try { + return InetAddress.getLocalHost().getHostAddress(); + } catch (UnknownHostException e) { + } + return "127.0.0.1"; + } + + public static String getHostName() { + try { + return InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + } + return "未知"; + } +} \ No newline at end of file diff --git a/spring-boot-demo-websocket/src/main/resources/static/js/sockjs.min.js b/spring-boot-demo-websocket/src/main/resources/static/js/sockjs.min.js new file mode 100644 index 0000000..fe361c7 --- /dev/null +++ b/spring-boot-demo-websocket/src/main/resources/static/js/sockjs.min.js @@ -0,0 +1,27 @@ +/* SockJS client, version 0.3.4, http://sockjs.org, MIT License + +Copyright (c) 2011-2012 VMware, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// JSON2 by Douglas Crockford (minified). +var JSON;JSON||(JSON={}),function(){function str(a,b){var c,d,e,f,g=gap,h,i=b[a];i&&typeof i=="object"&&typeof i.toJSON=="function"&&(i=i.toJSON(a)),typeof rep=="function"&&(i=rep.call(b,a,i));switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";gap+=indent,h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;c