@@ -0,0 +1,18 @@ | |||
package com.xkcoding.websocket.common; | |||
/** | |||
* <p> | |||
* WebSocket常量 | |||
* </p> | |||
* | |||
* @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"; | |||
} |
@@ -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; | |||
/** | |||
* <p> | |||
* WebSocket配置 | |||
* </p> | |||
* | |||
* @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"); | |||
} | |||
} |
@@ -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; | |||
/** | |||
* <p> | |||
* 服务器相关信息实体 | |||
* </p> | |||
* | |||
* @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<SysFile> sysFiles = new LinkedList<SysFile>(); | |||
public Cpu getCpu() { | |||
return cpu; | |||
} | |||
public void setCpu(Cpu cpu) { | |||
this.cpu = cpu; | |||
} | |||
public Mem getMem() { | |||
return mem; | |||
} | |||
public void setMem(Mem mem) { | |||
this.mem = mem; | |||
} | |||
public Jvm getJvm() { | |||
return jvm; | |||
} | |||
public void setJvm(Jvm jvm) { | |||
this.jvm = jvm; | |||
} | |||
public Sys getSys() { | |||
return sys; | |||
} | |||
public void setSys(Sys sys) { | |||
this.sys = sys; | |||
} | |||
public List<SysFile> getSysFiles() { | |||
return sysFiles; | |||
} | |||
public void setSysFiles(List<SysFile> sysFiles) { | |||
this.sysFiles = sysFiles; | |||
} | |||
public void copyTo() throws Exception { | |||
SystemInfo si = new SystemInfo(); | |||
HardwareAbstractionLayer hal = si.getHardware(); | |||
setCpuInfo(hal.getProcessor()); | |||
setMemInfo(hal.getMemory()); | |||
setSysInfo(); | |||
setJvmInfo(); | |||
setSysFiles(si.getOperatingSystem()); | |||
} | |||
/** | |||
* 设置CPU信息 | |||
*/ | |||
private void setCpuInfo(CentralProcessor processor) { | |||
// CPU信息 | |||
long[] prevTicks = processor.getSystemCpuLoadTicks(); | |||
Util.sleep(OSHI_WAIT_SECOND); | |||
long[] ticks = processor.getSystemCpuLoadTicks(); | |||
long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()]; | |||
long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()]; | |||
long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()]; | |||
long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()]; | |||
long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()]; | |||
long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()]; | |||
long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()]; | |||
long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()]; | |||
long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal; | |||
cpu.setCpuNum(processor.getLogicalProcessorCount()); | |||
cpu.setTotal(totalCpu); | |||
cpu.setSys(cSys); | |||
cpu.setUsed(user); | |||
cpu.setWait(iowait); | |||
cpu.setFree(idle); | |||
} | |||
/** | |||
* 设置内存信息 | |||
*/ | |||
private void setMemInfo(GlobalMemory memory) { | |||
mem.setTotal(memory.getTotal()); | |||
mem.setUsed(memory.getTotal() - memory.getAvailable()); | |||
mem.setFree(memory.getAvailable()); | |||
} | |||
/** | |||
* 设置服务器信息 | |||
*/ | |||
private void setSysInfo() { | |||
Properties props = System.getProperties(); | |||
sys.setComputerName(IpUtil.getHostName()); | |||
sys.setComputerIp(IpUtil.getHostIp()); | |||
sys.setOsName(props.getProperty("os.name")); | |||
sys.setOsArch(props.getProperty("os.arch")); | |||
sys.setUserDir(props.getProperty("user.dir")); | |||
} | |||
/** | |||
* 设置Java虚拟机 | |||
*/ | |||
private void setJvmInfo() throws UnknownHostException { | |||
Properties props = System.getProperties(); | |||
jvm.setTotal(Runtime.getRuntime().totalMemory()); | |||
jvm.setMax(Runtime.getRuntime().maxMemory()); | |||
jvm.setFree(Runtime.getRuntime().freeMemory()); | |||
jvm.setVersion(props.getProperty("java.version")); | |||
jvm.setHome(props.getProperty("java.home")); | |||
} | |||
/** | |||
* 设置磁盘信息 | |||
*/ | |||
private void setSysFiles(OperatingSystem os) { | |||
FileSystem fileSystem = os.getFileSystem(); | |||
OSFileStore[] fsArray = fileSystem.getFileStores(); | |||
for (OSFileStore fs : fsArray) { | |||
long free = fs.getUsableSpace(); | |||
long total = fs.getTotalSpace(); | |||
long used = total - free; | |||
SysFile sysFile = new SysFile(); | |||
sysFile.setDirName(fs.getMount()); | |||
sysFile.setSysTypeName(fs.getType()); | |||
sysFile.setTypeName(fs.getName()); | |||
sysFile.setTotal(convertFileSize(total)); | |||
sysFile.setFree(convertFileSize(free)); | |||
sysFile.setUsed(convertFileSize(used)); | |||
sysFile.setUsage(NumberUtil.mul(NumberUtil.div(used, total, 4), 100)); | |||
sysFiles.add(sysFile); | |||
} | |||
} | |||
/** | |||
* 字节转换 | |||
* | |||
* @param size 字节大小 | |||
* @return 转换后值 | |||
*/ | |||
public String convertFileSize(long size) { | |||
long kb = 1024; | |||
long mb = kb * 1024; | |||
long gb = mb * 1024; | |||
if (size >= gb) { | |||
return String.format("%.1f GB", (float) size / gb); | |||
} else if (size >= mb) { | |||
float f = (float) size / mb; | |||
return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f); | |||
} else if (size >= kb) { | |||
float f = (float) size / kb; | |||
return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f); | |||
} else { | |||
return String.format("%d B", size); | |||
} | |||
} | |||
} |
@@ -0,0 +1,101 @@ | |||
package com.xkcoding.websocket.model.server; | |||
import cn.hutool.core.util.NumberUtil; | |||
/** | |||
* <p> | |||
* CPU相关信息实体 | |||
* </p> | |||
* | |||
* @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; | |||
} | |||
} |
@@ -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; | |||
/** | |||
* <p> | |||
* JVM相关信息实体 | |||
* </p> | |||
* | |||
* @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); | |||
} | |||
} |
@@ -0,0 +1,61 @@ | |||
package com.xkcoding.websocket.model.server; | |||
import cn.hutool.core.util.NumberUtil; | |||
/** | |||
* <p> | |||
* 內存相关信息实体 | |||
* </p> | |||
* | |||
* @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); | |||
} | |||
} |
@@ -0,0 +1,81 @@ | |||
package com.xkcoding.websocket.model.server; | |||
/** | |||
* <p> | |||
* 系统相关信息实体 | |||
* </p> | |||
* | |||
* @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; | |||
} | |||
} |
@@ -0,0 +1,107 @@ | |||
package com.xkcoding.websocket.model.server; | |||
/** | |||
* <p> | |||
* 系统文件相关信息实体 | |||
* </p> | |||
* | |||
* @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; | |||
} | |||
} |
@@ -0,0 +1,33 @@ | |||
package com.xkcoding.websocket.payload; | |||
import lombok.AllArgsConstructor; | |||
import lombok.Data; | |||
import lombok.NoArgsConstructor; | |||
/** | |||
* <p> | |||
* 键值匹配 | |||
* </p> | |||
* | |||
* @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; | |||
} |
@@ -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; | |||
/** | |||
* <p> | |||
* 服务器信息VO | |||
* </p> | |||
* | |||
* @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<CpuVO> cpu = Lists.newArrayList(); | |||
List<JvmVO> jvm = Lists.newArrayList(); | |||
List<MemVO> mem = Lists.newArrayList(); | |||
List<SysFileVO> sysFile = Lists.newArrayList(); | |||
List<SysVO> sys = Lists.newArrayList(); | |||
public ServerVO create(Server server) { | |||
cpu.add(CpuVO.create(server.getCpu())); | |||
jvm.add(JvmVO.create(server.getJvm())); | |||
mem.add(MemVO.create(server.getMem())); | |||
sysFile.add(SysFileVO.create(server.getSysFiles())); | |||
sys.add(SysVO.create(server.getSys())); | |||
return null; | |||
} | |||
} |
@@ -0,0 +1,37 @@ | |||
package com.xkcoding.websocket.payload.server; | |||
import com.google.common.collect.Lists; | |||
import com.xkcoding.websocket.model.server.Cpu; | |||
import com.xkcoding.websocket.payload.KV; | |||
import lombok.Data; | |||
import java.util.List; | |||
/** | |||
* <p> | |||
* CPU相关信息实体VO | |||
* </p> | |||
* | |||
* @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<KV> data = Lists.newArrayList(); | |||
public static CpuVO create(Cpu cpu) { | |||
CpuVO vo = new CpuVO(); | |||
vo.data.add(new KV("核心数", cpu.getCpuNum())); | |||
vo.data.add(new KV("CPU总的使用率", cpu.getTotal())); | |||
vo.data.add(new KV("CPU系统使用率", cpu.getSys())); | |||
vo.data.add(new KV("CPU用户使用率", cpu.getUsed())); | |||
vo.data.add(new KV("CPU当前等待率", cpu.getWait())); | |||
vo.data.add(new KV("CPU当前空闲率", cpu.getFree())); | |||
return vo; | |||
} | |||
} |
@@ -0,0 +1,39 @@ | |||
package com.xkcoding.websocket.payload.server; | |||
import com.google.common.collect.Lists; | |||
import com.xkcoding.websocket.model.server.Jvm; | |||
import com.xkcoding.websocket.payload.KV; | |||
import lombok.Data; | |||
import java.util.List; | |||
/** | |||
* <p> | |||
* JVM相关信息实体VO | |||
* </p> | |||
* | |||
* @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<KV> data = Lists.newArrayList(); | |||
public static JvmVO create(Jvm jvm) { | |||
JvmVO vo = new JvmVO(); | |||
vo.data.add(new KV("当前JVM占用的内存总数(M)", jvm.getTotal())); | |||
vo.data.add(new KV("JVM最大可用内存总数(M)", jvm.getMax())); | |||
vo.data.add(new KV("JVM空闲内存(M)", jvm.getFree())); | |||
vo.data.add(new KV("JDK版本", jvm.getVersion())); | |||
vo.data.add(new KV("JDK路径", jvm.getHome())); | |||
vo.data.add(new KV("JDK启动时间", jvm.getStartTime())); | |||
vo.data.add(new KV("JDK运行时间", jvm.getRunTime())); | |||
return vo; | |||
} | |||
} |
@@ -0,0 +1,34 @@ | |||
package com.xkcoding.websocket.payload.server; | |||
import com.google.common.collect.Lists; | |||
import com.xkcoding.websocket.model.server.Mem; | |||
import com.xkcoding.websocket.payload.KV; | |||
import lombok.Data; | |||
import java.util.List; | |||
/** | |||
* <p> | |||
* 內存相关信息实体VO | |||
* </p> | |||
* | |||
* @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<KV> data = Lists.newArrayList(); | |||
public static MemVO create(Mem mem) { | |||
MemVO vo = new MemVO(); | |||
vo.data.add(new KV("内存总量", mem.getTotal())); | |||
vo.data.add(new KV("已用内存", mem.getUsed())); | |||
vo.data.add(new KV("剩余内存", mem.getFree())); | |||
return vo; | |||
} | |||
} |
@@ -0,0 +1,44 @@ | |||
package com.xkcoding.websocket.payload.server; | |||
import com.google.common.collect.Lists; | |||
import com.xkcoding.websocket.model.server.SysFile; | |||
import com.xkcoding.websocket.payload.KV; | |||
import lombok.Data; | |||
import java.util.List; | |||
/** | |||
* <p> | |||
* 系统文件相关信息实体VO | |||
* </p> | |||
* | |||
* @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<List<KV>> data = Lists.newArrayList(); | |||
public static SysFileVO create(List<SysFile> sysFiles) { | |||
SysFileVO vo = new SysFileVO(); | |||
for (SysFile sysFile : sysFiles) { | |||
List<KV> item = Lists.newArrayList(); | |||
item.add(new KV("盘符路径", sysFile.getDirName())); | |||
item.add(new KV("盘符类型", sysFile.getSysTypeName())); | |||
item.add(new KV("文件类型", sysFile.getTypeName())); | |||
item.add(new KV("总大小", sysFile.getTotal())); | |||
item.add(new KV("剩余大小", sysFile.getFree())); | |||
item.add(new KV("已经使用量", sysFile.getUsed())); | |||
item.add(new KV("资源的使用率", sysFile.getUsage())); | |||
vo.data.add(item); | |||
} | |||
return vo; | |||
} | |||
} |
@@ -0,0 +1,36 @@ | |||
package com.xkcoding.websocket.payload.server; | |||
import com.google.common.collect.Lists; | |||
import com.xkcoding.websocket.model.server.Sys; | |||
import com.xkcoding.websocket.payload.KV; | |||
import lombok.Data; | |||
import java.util.List; | |||
/** | |||
* <p> | |||
* 系统相关信息实体VO | |||
* </p> | |||
* | |||
* @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<KV> data = Lists.newArrayList(); | |||
public static SysVO create(Sys sys) { | |||
SysVO vo = new SysVO(); | |||
vo.data.add(new KV("服务器名称", sys.getComputerName())); | |||
vo.data.add(new KV("服务器Ip", sys.getComputerIp())); | |||
vo.data.add(new KV("项目路径", sys.getUserDir())); | |||
vo.data.add(new KV("操作系统", sys.getOsName())); | |||
vo.data.add(new KV("系统架构", sys.getOsArch())); | |||
return vo; | |||
} | |||
} |
@@ -0,0 +1,49 @@ | |||
package com.xkcoding.websocket.task; | |||
import cn.hutool.core.date.DateUtil; | |||
import cn.hutool.json.JSONUtil; | |||
import com.xkcoding.websocket.common.WebSocketConsts; | |||
import com.xkcoding.websocket.model.Server; | |||
import com.xkcoding.websocket.payload.ServerVO; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.messaging.simp.SimpMessagingTemplate; | |||
import org.springframework.scheduling.annotation.Scheduled; | |||
import org.springframework.stereotype.Component; | |||
import java.util.Date; | |||
/** | |||
* <p> | |||
* 服务器定时推送任务 | |||
* </p> | |||
* | |||
* @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())); | |||
} | |||
} |
@@ -0,0 +1,169 @@ | |||
package com.xkcoding.websocket.util; | |||
import javax.servlet.http.HttpServletRequest; | |||
import java.net.InetAddress; | |||
import java.net.UnknownHostException; | |||
/** | |||
* <p> | |||
* IP 工具类 | |||
* </p> | |||
* | |||
* @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 "未知"; | |||
} | |||
} |
@@ -0,0 +1,501 @@ | |||
// Generated by CoffeeScript 1.7.1 | |||
/* | |||
Stomp Over WebSocket http://www.jmesnil.net/stomp-websocket/doc/ | Apache License V2.0 | |||
Copyright (C) 2010-2013 [Jeff Mesnil](http://jmesnil.net/) | |||
Copyright (C) 2012 [FuseSource, Inc.](http://fusesource.com) | |||
*/ | |||
(function() { | |||
var Byte, Client, Frame, Stomp, | |||
__hasProp = {}.hasOwnProperty, | |||
__slice = [].slice; | |||
Byte = { | |||
LF: '\x0A', | |||
NULL: '\x00' | |||
}; | |||
Frame = (function() { | |||
var unmarshallSingle; | |||
function Frame(command, headers, body) { | |||
this.command = command; | |||
this.headers = headers != null ? headers : {}; | |||
this.body = body != null ? body : ''; | |||
} | |||
Frame.prototype.toString = function() { | |||
var lines, name, skipContentLength, value, _ref; | |||
lines = [this.command]; | |||
skipContentLength = this.headers['content-length'] === false ? true : false; | |||
if (skipContentLength) { | |||
delete this.headers['content-length']; | |||
} | |||
_ref = this.headers; | |||
for (name in _ref) { | |||
if (!__hasProp.call(_ref, name)) continue; | |||
value = _ref[name]; | |||
lines.push("" + name + ":" + value); | |||
} | |||
if (this.body && !skipContentLength) { | |||
lines.push("content-length:" + (Frame.sizeOfUTF8(this.body))); | |||
} | |||
lines.push(Byte.LF + this.body); | |||
return lines.join(Byte.LF); | |||
}; | |||
Frame.sizeOfUTF8 = function(s) { | |||
if (s) { | |||
return encodeURI(s).match(/%..|./g).length; | |||
} else { | |||
return 0; | |||
} | |||
}; | |||
unmarshallSingle = function(data) { | |||
var body, chr, command, divider, headerLines, headers, i, idx, len, line, start, trim, _i, _j, _len, _ref, _ref1; | |||
divider = data.search(RegExp("" + Byte.LF + Byte.LF)); | |||
headerLines = data.substring(0, divider).split(Byte.LF); | |||
command = headerLines.shift(); | |||
headers = {}; | |||
trim = function(str) { | |||
return str.replace(/^\s+|\s+$/g, ''); | |||
}; | |||
_ref = headerLines.reverse(); | |||
for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |||
line = _ref[_i]; | |||
idx = line.indexOf(':'); | |||
headers[trim(line.substring(0, idx))] = trim(line.substring(idx + 1)); | |||
} | |||
body = ''; | |||
start = divider + 2; | |||
if (headers['content-length']) { | |||
len = parseInt(headers['content-length']); | |||
body = ('' + data).substring(start, start + len); | |||
} else { | |||
chr = null; | |||
for (i = _j = start, _ref1 = data.length; start <= _ref1 ? _j < _ref1 : _j > _ref1; i = start <= _ref1 ? ++_j : --_j) { | |||
chr = data.charAt(i); | |||
if (chr === Byte.NULL) { | |||
break; | |||
} | |||
body += chr; | |||
} | |||
} | |||
return new Frame(command, headers, body); | |||
}; | |||
Frame.unmarshall = function(datas) { | |||
var frame, frames, last_frame, r; | |||
frames = datas.split(RegExp("" + Byte.NULL + Byte.LF + "*")); | |||
r = { | |||
frames: [], | |||
partial: '' | |||
}; | |||
r.frames = (function() { | |||
var _i, _len, _ref, _results; | |||
_ref = frames.slice(0, -1); | |||
_results = []; | |||
for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |||
frame = _ref[_i]; | |||
_results.push(unmarshallSingle(frame)); | |||
} | |||
return _results; | |||
})(); | |||
last_frame = frames.slice(-1)[0]; | |||
if (last_frame === Byte.LF || (last_frame.search(RegExp("" + Byte.NULL + Byte.LF + "*$"))) !== -1) { | |||
r.frames.push(unmarshallSingle(last_frame)); | |||
} else { | |||
r.partial = last_frame; | |||
} | |||
return r; | |||
}; | |||
Frame.marshall = function(command, headers, body) { | |||
var frame; | |||
frame = new Frame(command, headers, body); | |||
return frame.toString() + Byte.NULL; | |||
}; | |||
return Frame; | |||
})(); | |||
Client = (function() { | |||
var now; | |||
function Client(ws) { | |||
this.ws = ws; | |||
this.ws.binaryType = "arraybuffer"; | |||
this.counter = 0; | |||
this.connected = false; | |||
this.heartbeat = { | |||
outgoing: 10000, | |||
incoming: 10000 | |||
}; | |||
this.maxWebSocketFrameSize = 16 * 1024; | |||
this.subscriptions = {}; | |||
this.partialData = ''; | |||
} | |||
Client.prototype.debug = function(message) { | |||
var _ref; | |||
return typeof window !== "undefined" && window !== null ? (_ref = window.console) != null ? _ref.log(message) : void 0 : void 0; | |||
}; | |||
now = function() { | |||
if (Date.now) { | |||
return Date.now(); | |||
} else { | |||
return new Date().valueOf; | |||
} | |||
}; | |||
Client.prototype._transmit = function(command, headers, body) { | |||
var out; | |||
out = Frame.marshall(command, headers, body); | |||
if (typeof this.debug === "function") { | |||
this.debug(">>> " + out); | |||
} | |||
while (true) { | |||
if (out.length > this.maxWebSocketFrameSize) { | |||
this.ws.send(out.substring(0, this.maxWebSocketFrameSize)); | |||
out = out.substring(this.maxWebSocketFrameSize); | |||
if (typeof this.debug === "function") { | |||
this.debug("remaining = " + out.length); | |||
} | |||
} else { | |||
return this.ws.send(out); | |||
} | |||
} | |||
}; | |||
Client.prototype._setupHeartbeat = function(headers) { | |||
var serverIncoming, serverOutgoing, ttl, v, _ref, _ref1; | |||
if ((_ref = headers.version) !== Stomp.VERSIONS.V1_1 && _ref !== Stomp.VERSIONS.V1_2) { | |||
return; | |||
} | |||
_ref1 = (function() { | |||
var _i, _len, _ref1, _results; | |||
_ref1 = headers['heart-beat'].split(","); | |||
_results = []; | |||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) { | |||
v = _ref1[_i]; | |||
_results.push(parseInt(v)); | |||
} | |||
return _results; | |||
})(), serverOutgoing = _ref1[0], serverIncoming = _ref1[1]; | |||
if (!(this.heartbeat.outgoing === 0 || serverIncoming === 0)) { | |||
ttl = Math.max(this.heartbeat.outgoing, serverIncoming); | |||
if (typeof this.debug === "function") { | |||
this.debug("send PING every " + ttl + "ms"); | |||
} | |||
this.pinger = Stomp.setInterval(ttl, (function(_this) { | |||
return function() { | |||
_this.ws.send(Byte.LF); | |||
return typeof _this.debug === "function" ? _this.debug(">>> PING") : void 0; | |||
}; | |||
})(this)); | |||
} | |||
if (!(this.heartbeat.incoming === 0 || serverOutgoing === 0)) { | |||
ttl = Math.max(this.heartbeat.incoming, serverOutgoing); | |||
if (typeof this.debug === "function") { | |||
this.debug("check PONG every " + ttl + "ms"); | |||
} | |||
return this.ponger = Stomp.setInterval(ttl, (function(_this) { | |||
return function() { | |||
var delta; | |||
delta = now() - _this.serverActivity; | |||
if (delta > ttl * 2) { | |||
if (typeof _this.debug === "function") { | |||
_this.debug("did not receive server activity for the last " + delta + "ms"); | |||
} | |||
return _this.ws.close(); | |||
} | |||
}; | |||
})(this)); | |||
} | |||
}; | |||
Client.prototype._parseConnect = function() { | |||
var args, connectCallback, errorCallback, headers; | |||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | |||
headers = {}; | |||
switch (args.length) { | |||
case 2: | |||
headers = args[0], connectCallback = args[1]; | |||
break; | |||
case 3: | |||
if (args[1] instanceof Function) { | |||
headers = args[0], connectCallback = args[1], errorCallback = args[2]; | |||
} else { | |||
headers.login = args[0], headers.passcode = args[1], connectCallback = args[2]; | |||
} | |||
break; | |||
case 4: | |||
headers.login = args[0], headers.passcode = args[1], connectCallback = args[2], errorCallback = args[3]; | |||
break; | |||
default: | |||
headers.login = args[0], headers.passcode = args[1], connectCallback = args[2], errorCallback = args[3], headers.host = args[4]; | |||
} | |||
return [headers, connectCallback, errorCallback]; | |||
}; | |||
Client.prototype.connect = function() { | |||
var args, errorCallback, headers, out; | |||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; | |||
out = this._parseConnect.apply(this, args); | |||
headers = out[0], this.connectCallback = out[1], errorCallback = out[2]; | |||
if (typeof this.debug === "function") { | |||
this.debug("Opening Web Socket..."); | |||
} | |||
this.ws.onmessage = (function(_this) { | |||
return function(evt) { | |||
var arr, c, client, data, frame, messageID, onreceive, subscription, unmarshalledData, _i, _len, _ref, _results; | |||
data = typeof ArrayBuffer !== 'undefined' && evt.data instanceof ArrayBuffer ? (arr = new Uint8Array(evt.data), typeof _this.debug === "function" ? _this.debug("--- got data length: " + arr.length) : void 0, ((function() { | |||
var _i, _len, _results; | |||
_results = []; | |||
for (_i = 0, _len = arr.length; _i < _len; _i++) { | |||
c = arr[_i]; | |||
_results.push(String.fromCharCode(c)); | |||
} | |||
return _results; | |||
})()).join('')) : evt.data; | |||
_this.serverActivity = now(); | |||
if (data === Byte.LF) { | |||
if (typeof _this.debug === "function") { | |||
_this.debug("<<< PONG"); | |||
} | |||
return; | |||
} | |||
if (typeof _this.debug === "function") { | |||
_this.debug("<<< " + data); | |||
} | |||
unmarshalledData = Frame.unmarshall(_this.partialData + data); | |||
_this.partialData = unmarshalledData.partial; | |||
_ref = unmarshalledData.frames; | |||
_results = []; | |||
for (_i = 0, _len = _ref.length; _i < _len; _i++) { | |||
frame = _ref[_i]; | |||
switch (frame.command) { | |||
case "CONNECTED": | |||
if (typeof _this.debug === "function") { | |||
_this.debug("connected to server " + frame.headers.server); | |||
} | |||
_this.connected = true; | |||
_this._setupHeartbeat(frame.headers); | |||
_results.push(typeof _this.connectCallback === "function" ? _this.connectCallback(frame) : void 0); | |||
break; | |||
case "MESSAGE": | |||
subscription = frame.headers.subscription; | |||
onreceive = _this.subscriptions[subscription] || _this.onreceive; | |||
if (onreceive) { | |||
client = _this; | |||
messageID = frame.headers["message-id"]; | |||
frame.ack = function(headers) { | |||
if (headers == null) { | |||
headers = {}; | |||
} | |||
return client.ack(messageID, subscription, headers); | |||
}; | |||
frame.nack = function(headers) { | |||
if (headers == null) { | |||
headers = {}; | |||
} | |||
return client.nack(messageID, subscription, headers); | |||
}; | |||
_results.push(onreceive(frame)); | |||
} else { | |||
_results.push(typeof _this.debug === "function" ? _this.debug("Unhandled received MESSAGE: " + frame) : void 0); | |||
} | |||
break; | |||
case "RECEIPT": | |||
_results.push(typeof _this.onreceipt === "function" ? _this.onreceipt(frame) : void 0); | |||
break; | |||
case "ERROR": | |||
_results.push(typeof errorCallback === "function" ? errorCallback(frame) : void 0); | |||
break; | |||
default: | |||
_results.push(typeof _this.debug === "function" ? _this.debug("Unhandled frame: " + frame) : void 0); | |||
} | |||
} | |||
return _results; | |||
}; | |||
})(this); | |||
this.ws.onclose = (function(_this) { | |||
return function() { | |||
var msg; | |||
msg = "Whoops! Lost connection to " + _this.ws.url; | |||
if (typeof _this.debug === "function") { | |||
_this.debug(msg); | |||
} | |||
_this._cleanUp(); | |||
return typeof errorCallback === "function" ? errorCallback(msg) : void 0; | |||
}; | |||
})(this); | |||
return this.ws.onopen = (function(_this) { | |||
return function() { | |||
if (typeof _this.debug === "function") { | |||
_this.debug('Web Socket Opened...'); | |||
} | |||
headers["accept-version"] = Stomp.VERSIONS.supportedVersions(); | |||
headers["heart-beat"] = [_this.heartbeat.outgoing, _this.heartbeat.incoming].join(','); | |||
return _this._transmit("CONNECT", headers); | |||
}; | |||
})(this); | |||
}; | |||
Client.prototype.disconnect = function(disconnectCallback, headers) { | |||
if (headers == null) { | |||
headers = {}; | |||
} | |||
this._transmit("DISCONNECT", headers); | |||
this.ws.onclose = null; | |||
this.ws.close(); | |||
this._cleanUp(); | |||
return typeof disconnectCallback === "function" ? disconnectCallback() : void 0; | |||
}; | |||
Client.prototype._cleanUp = function() { | |||
this.connected = false; | |||
if (this.pinger) { | |||
Stomp.clearInterval(this.pinger); | |||
} | |||
if (this.ponger) { | |||
return Stomp.clearInterval(this.ponger); | |||
} | |||
}; | |||
Client.prototype.send = function(destination, headers, body) { | |||
if (headers == null) { | |||
headers = {}; | |||
} | |||
if (body == null) { | |||
body = ''; | |||
} | |||
headers.destination = destination; | |||
return this._transmit("SEND", headers, body); | |||
}; | |||
Client.prototype.subscribe = function(destination, callback, headers) { | |||
var client; | |||
if (headers == null) { | |||
headers = {}; | |||
} | |||
if (!headers.id) { | |||
headers.id = "sub-" + this.counter++; | |||
} | |||
headers.destination = destination; | |||
this.subscriptions[headers.id] = callback; | |||
this._transmit("SUBSCRIBE", headers); | |||
client = this; | |||
return { | |||
id: headers.id, | |||
unsubscribe: function() { | |||
return client.unsubscribe(headers.id); | |||
} | |||
}; | |||
}; | |||
Client.prototype.unsubscribe = function(id) { | |||
delete this.subscriptions[id]; | |||
return this._transmit("UNSUBSCRIBE", { | |||
id: id | |||
}); | |||
}; | |||
Client.prototype.begin = function(transaction) { | |||
var client, txid; | |||
txid = transaction || "tx-" + this.counter++; | |||
this._transmit("BEGIN", { | |||
transaction: txid | |||
}); | |||
client = this; | |||
return { | |||
id: txid, | |||
commit: function() { | |||
return client.commit(txid); | |||
}, | |||
abort: function() { | |||
return client.abort(txid); | |||
} | |||
}; | |||
}; | |||
Client.prototype.commit = function(transaction) { | |||
return this._transmit("COMMIT", { | |||
transaction: transaction | |||
}); | |||
}; | |||
Client.prototype.abort = function(transaction) { | |||
return this._transmit("ABORT", { | |||
transaction: transaction | |||
}); | |||
}; | |||
Client.prototype.ack = function(messageID, subscription, headers) { | |||
if (headers == null) { | |||
headers = {}; | |||
} | |||
headers["message-id"] = messageID; | |||
headers.subscription = subscription; | |||
return this._transmit("ACK", headers); | |||
}; | |||
Client.prototype.nack = function(messageID, subscription, headers) { | |||
if (headers == null) { | |||
headers = {}; | |||
} | |||
headers["message-id"] = messageID; | |||
headers.subscription = subscription; | |||
return this._transmit("NACK", headers); | |||
}; | |||
return Client; | |||
})(); | |||
Stomp = { | |||
VERSIONS: { | |||
V1_0: '1.0', | |||
V1_1: '1.1', | |||
V1_2: '1.2', | |||
supportedVersions: function() { | |||
return '1.1,1.0'; | |||
} | |||
}, | |||
client: function(url, protocols) { | |||
var klass, ws; | |||
if (protocols == null) { | |||
protocols = ['v10.stomp', 'v11.stomp']; | |||
} | |||
klass = Stomp.WebSocketClass || WebSocket; | |||
ws = new klass(url, protocols); | |||
return new Client(ws); | |||
}, | |||
over: function(ws) { | |||
return new Client(ws); | |||
}, | |||
Frame: Frame | |||
}; | |||
if (typeof exports !== "undefined" && exports !== null) { | |||
exports.Stomp = Stomp; | |||
} | |||
if (typeof window !== "undefined" && window !== null) { | |||
Stomp.setInterval = function(interval, f) { | |||
return window.setInterval(f, interval); | |||
}; | |||
Stomp.clearInterval = function(id) { | |||
return window.clearInterval(id); | |||
}; | |||
window.Stomp = Stomp; | |||
} else if (!exports) { | |||
self.Stomp = Stomp; | |||
} | |||
}).call(this); |
@@ -0,0 +1,97 @@ | |||
<!DOCTYPE html> | |||
<html lang="en"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<title>服务器信息</title> | |||
<!-- import CSS --> | |||
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> | |||
</head> | |||
<body> | |||
<div id="app"> | |||
<el-container> | |||
<el-header> | |||
<el-button @click="_initSockJs">手动连接</el-button> | |||
<el-button @click="_destroySockJs" danger>断开连接</el-button> | |||
</el-header> | |||
<el-main> | |||
<el-row v-if="server.cpu.length > 0"> | |||
<el-col :span="16" :offset="4"> | |||
<el-card class="box-card"> | |||
<div slot="header"> | |||
<span>CPU信息</span> | |||
</div> | |||
<el-table :data="server.cpu[0].data" style="width: 100%"> | |||
<el-table-column prop="key" label="属性"> | |||
</el-table-column> | |||
<el-table-column prop="value" label="值"> | |||
</el-table-column> | |||
</el-table> | |||
</el-card> | |||
</el-col> | |||
</el-row> | |||
</el-main> | |||
</el-container> | |||
</div> | |||
</body> | |||
<script src="js/sockjs.min.js"></script> | |||
<script src="js/stomp.js"></script> | |||
<!-- import Vue before Element --> | |||
<script src="https://unpkg.com/vue/dist/vue.js"></script> | |||
<!-- import JavaScript --> | |||
<script src="https://unpkg.com/element-ui/lib/index.js"></script> | |||
<script> | |||
const wsHost = "http://localhost:8080/demo/notification"; | |||
const wsTopic = "/topic/server"; | |||
const app = new Vue({ | |||
el: '#app', | |||
data: function () { | |||
return { | |||
stompClient: {}, | |||
socket: {}, | |||
server: { | |||
cpu: [], | |||
jvm: [], | |||
mem: [], | |||
sysFile: [], | |||
sys: [] | |||
} | |||
} | |||
}, | |||
methods: { | |||
_initSockJs() { | |||
this.socket = new SockJS(wsHost); | |||
this.stompClient = Stomp.over(this.socket); | |||
this.stompClient.connect({}, (frame) => { | |||
console.log('websocket连接成功:' + frame); | |||
this.$message('websocket服务器连接成功'); | |||
// 另外再注册一下消息推送 | |||
this.stompClient.subscribe(wsTopic, function (response) { | |||
this.server = JSON.parse(response); | |||
}); | |||
}); | |||
}, | |||
_destroySockJs() { | |||
if (this.stompClient != null) { | |||
this.stompClient.disconnect(); | |||
this.socket.onclose; | |||
this.socket.close(); | |||
this.stompClient = {}; | |||
this.socket = {}; | |||
} | |||
console.log('websocket断开成功!'); | |||
this.$message.error('websocket断开成功!'); | |||
} | |||
}, | |||
mounted() { | |||
this._initSockJs(); | |||
}, | |||
beforeDestroy() { | |||
this._destroySockJs(); | |||
} | |||
}) | |||
</script> | |||
</html> |