后端java springboot 项目
简单websocket server 端代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.cloudkd</groupId> <artifactId>websocket-server</artifactId> <version>1.0</version> <packaging>jar</packaging>
<name>websocket</name> <description>websocket for Spring Boot</description>
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> </parent>
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties>
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>2.0.20</version> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
</project>
|
// 定义相关地址,以及session集合,用户存储管理client
ws://{ip}:{port}/websocket/data
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
| package com.cloudkd.websocket;
import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint;
import com.alibaba.fastjson.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component;
@ServerEndpoint("/websocket/data") @Component public class WebSocketServer { private static final Logger log = LoggerFactory.getLogger(WebSocketServer.class); private static int onlineCount = 0; private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
private Session session;
public static void kill(String id) { for (WebSocketServer item : webSocketSet) { try { if (item.session.getId().equals(id)) { log.info("Kill {} success", id); item.session.close(); } } catch (IOException ignored) { } } }
public static Map<String, Object> getAllSessionIds() { Map<String, Object> map = new HashMap<>(); for (WebSocketServer item : webSocketSet) { map.put(item.session.getId(),item.session.getId()); } return map; }
@OnOpen public void onOpen(Session session) { this.session = session; webSocketSet.add(this); addOnlineCount(); log.info("有新连接加入!当前在线人数为" + getOnlineCount()); try { sendMessage("连接成功"); } catch (IOException e) { log.error("websocket IO异常"); } }
@OnClose public void onClose() { webSocketSet.remove(this); subOnlineCount(); log.info("有一连接关闭!当前在线人数为" + getOnlineCount()); }
@OnMessage public void onMessage(String message, Session session) { log.info("来自客户端的消息 sessionId = {} ,data :{}", session.getId(), message);
}
@OnError public void onError(Session session, Throwable error) { log.error("发生错误"); error.printStackTrace(); }
public void sendMessage(String message) throws IOException { this.session.getBasicRemote().sendText(message); }
public static void sendInfo(BodyEntity message) { log.info("SEND MESSAGE:{}", message);
for (WebSocketServer item : webSocketSet) { try { if (item.session.getId().equals(message.getSessionId())) { JSONObject sa = JSONObject.parseObject(message.getMessage()); item.sendMessage(sa.toString()); } } catch (IOException ignored) { } } }
private static synchronized int getOnlineCount() { return onlineCount; }
private static synchronized void addOnlineCount() { WebSocketServer.onlineCount++; }
private static synchronized void subOnlineCount() { WebSocketServer.onlineCount--; } }
|
// WebSocketConfig 相关配置
1 2 3 4 5 6 7 8 9 10 11 12 13
| package com.cloudkd.websocket;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
|
// 管理api,可往对应连接发送消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| package com.cloudkd.websocket;
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.*;
import java.util.HashMap; import java.util.Map;
@RestController public class ManageController { private final Logger logger = LoggerFactory.getLogger(this.getClass());
@PostMapping(value = "/pushData") public Map<String, Object> pushVideoListToWeb(@RequestBody BodyEntity message) { Map<String, Object> result = new HashMap<String, Object>(); try { WebSocketServer.sendInfo(message); result.put("operationResult", true); } catch (Exception e) { result.put("operationResult", true); } return result; }
@GetMapping(value = "/kill") public Map<String, Object> pushVideoListToWeb(String id) { WebSocketServer.kill(id); return new HashMap<>(); }
@GetMapping(value = "/getAll") public Map<String, Object> getAll() { return WebSocketServer.getAllSessionIds(); } }
package com.cloudkd.websocket; public class MessageEntity { private String message; private String sessionId;
public String getMessage() { return message; }
public void setMessage(String message) { this.message = message; }
public String getSessionId() { return sessionId; }
public void setSessionId(String sessionId) { this.sessionId = sessionId; } }
|
// 测试页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>server地址 :</h3> <input id="serveraddress" type="text" value="ws://192.168.102.17:28080/elevator/realData" style="width: 500px;%"/><br/> <h3>您的用户id :</h3> <input id="userId" type="text"/><br/> <button onclick="initSocket()">连接</button> <br/>
=====================================================<br/> 消息 : <input id="message" type="text"/><br/> <button onclick="send()">发送</button> <br/> =====================================================<br/> 连接状态 : <button onclick="clearConnectStatu()">清空</button> <br/> <div id="connectStatu"></div> <br/>
=====================================================<br/> 收到消息 :<br/> <div id="receivedMessage"></div> <br/> =====================================================<br/> 心跳 :<br/> <div id="heartdiv"></div> <br/>
</body>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> <script type="text/javascript"> var heartflag = false; var webSocket = null; var tryTime = 0; $(function () {
window.onbeforeunload = function () {
}; });
function initSocket() { var serveraddress = $("#serveraddress").val(); var userId = $("#userId").val();
if (!window.WebSocket) { $("#connectStatu").append(getNowFormatDate() + " 您的浏览器不支持ws<br/>"); return false; }
webSocket = new WebSocket(serveraddress);
webSocket.onmessage = function (msg) { if (msg.data !== "&") { $("#receivedMessage").append(getNowFormatDate() + " 收到消息 : " + msg.data + "<br/>"); } };
webSocket.onerror = function (event) { heartflag = false; $("#connectStatu").append(getNowFormatDate() + " 异常<br/>"); };
webSocket.onopen = function (event) { heartflag = true; heart(); $("#connectStatu").append(getNowFormatDate() + " 建立连接成功<br/>"); tryTime = 0; };
webSocket.onclose = function () { heartflag = false; if (tryTime < 10) { setTimeout(function () { webSocket = null; tryTime++; initSocket(); $("#connectStatu").append(getNowFormatDate() + " 第" + tryTime + "次重连<br/>"); }, 3 * 1000); } else { alert("重连失败."); } };
}
function send() { var message = $("#message").val(); webSocket.send(message); }
function clearConnectStatu() { $("#connectStatu").empty(); }
function getNowFormatDate() { var date = new Date(); var seperator1 = "-"; var seperator2 = ":"; var month = date.getMonth() + 1; var strDate = date.getDate(); if (month >= 1 && month <= 9) { month = "0" + month; } if (strDate >= 0 && strDate <= 9) { strDate = "0" + strDate; } var currentdate = date.getFullYear() + seperator1 + month + seperator1 + strDate + " " + date.getHours() + seperator2 + date.getMinutes() + seperator2 + date.getSeconds(); return currentdate; }
function heart() { if (heartflag) { webSocket.send("&"); $("#heartdiv").append(getNowFormatDate() + " 心跳 <br/>"); } setTimeout("heart()", 10 * 60 * 1000);
} </script> </html>
|
// 配置文件
// 启动Main
1 2 3 4 5 6 7
| @SpringBootApplication public class WebsocketApplication {
public static void main(String[] args) { SpringApplication.run(WebsocketApplication.class, args); } }
|
启动后默认,返回 http://{ip}:8081 ,进入测试页面