WebSocket 是一种网络通信协议。它与HTTP协议最大的不同在于,HTTP协议做不到服务器主动向客户端推送信息。
WebSocket
其最大的特点在于:服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。
Spring Boot项目搭建
前面的步骤就不再赘述了,我们直接从pom.xml里面添加的依赖开始吧。
1. pom.xml文件配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<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.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
2. application.yml配置
server:
port: 8888
spring:
freemarker:
prefix: classpath:/templates/
suffix: .html
3. index.html页面
<!DOCTYPE html>
<html>
<head>
<title>WebSoket Demo</title>
<script type="text/javascript">
//验证浏览器是否支持WebSocket协议
if (!window.WebSocket) {
alert("WebSocket not supported by this browser!");
}
let ws;
const log = function (s) {
if (document.readyState !== "complete") {
log.buffer.push(s);
} else {
document.getElementById("contentId").innerHTML += (s + "\n");
}
};
function display() {
ws = new WebSocket("ws://localhost:8888/websocket");
ws.onmessage = function (event) {
//监听消息
log(event.data);
};
ws.onclose = function (event) {
// 关闭WebSocket
console.log("ws close: " + event);
};
ws.onopen = function (event) {
// 打开WebSocket
console.log("ws open:" + event);
// 发送一个初始化消息
ws.send("Hello, Server!");
};
ws.onerror = function (event) {
// WebSocket异常
console.log("ws error:" + event);
};
}
function sendMsg() {
// 发送消息
const msg = document.getElementById("messageId");
ws.send(msg.value);
}
</script>
</head>
<body onload="display();">
<div id="valueLabel"></div>
<textarea rows="20" cols="30" id="contentId"></textarea>
<br/>
<input name="message" id="messageId"/>
<button id="sendButton" onClick="sendMsg()">Send</button>
</body>
</html>
4. 控制层
/**
* 测试控制器
* @author zhouzhaodong
*/
@Controller
public class TestController {
@RequestMapping("/")
public String view(){
return "index";
}
}
5. WebSocket配置类
/**
* WebSocket配置类
* @author zhouzhaodong
*/
@Configuration
public class WebsocketConfiguration {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
6. WebSocket服务端
/**
* WebSocket服务端
* @author zhouzhaodong
*/
@ServerEndpoint("/websocket")
@Component
@Slf4j
public class MyWebsocketServer {
/**
* 存放所有在线的客户端
*/
private static final Map<String, Session> CLIENTS = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session) {
log.info("有新的客户端连接了: {}", session.getId());
//将新用户存入在线的组
CLIENTS.put(session.getId(), session);
}
/**
* 客户端关闭
* @param session session
*/
@OnClose
public void onClose(Session session) {
log.info("有用户断开了, id为:{}", session.getId());
//将掉线的用户移除在线的组里
CLIENTS.remove(session.getId());
}
/**
* 发生错误
* @param throwable e
*/
@OnError
public void onError(Throwable throwable) {
throwable.printStackTrace();
}
/**
* 收到客户端发来消息
* @param message 消息对象
*/
@OnMessage
public void onMessage(String message) {
log.info("服务端收到客户端发来的消息: {}", message);
this.sendAll(message);
}
/**
* 群发消息
* @param message 消息内容
*/
private void sendAll(String message) {
for (Map.Entry<String, Session> sessionEntry : CLIENTS.entrySet()) {
sessionEntry.getValue().getAsyncRemote().sendText(message);
}
}
}
7. 启动项目,访问http://localhost:8888/查看项目:
输入信息,点击send按钮后就会发送信息啦。
后端控制台打印信息如下:
程序源码地址:
https://github.com/zhouzhaodong/springboot/tree/master/websocket
个人博客:
http://www.zhouzhaodong.xyz