1、导入依赖
<!--websocket依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
<version>2.6.2</version>
</dependency>
2、编写websocket的配置类
package com.study.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* 开启websocket支持
*/
@Configuration
public class WebSocketConfig {
//新建websocket配置类
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
3、自定义websocket
package com.study.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArrayList;
@Slf4j
@ServerEndpoint(value = "/websocket")
@Component
public class MyWebSocket {
//静态变量,用来记录当前在线连接人数,应该把他设计线程安全的
private static int onLineCount = 0;
//concurrent包的线程安全set,用来存放每个客户端对应的MyWebSocket对象
private static CopyOnWriteArrayList<MyWebSocket> webSockets = new CopyOnWriteArrayList<MyWebSocket>();
//与某个客户端的连接会话,需要通过它来给客户端发送数据
private Session session;
/*
建立连接成功调用的方法
*/
@OnOpen
public void onOpen(Session session){
this.session = session;
webSockets.add(this); //加入set中
addOnLineCount(); //在线数+1
System.out.println("有新连接加入!当前在线人数为:" + getOnLineCount());
try {
sendMessage("连接成功");
}catch (IOException e){
System.out.println("webSocket IO异常");
}
}
/*
连接关闭调用的方法
*/
@OnClose
public void onClose(){
webSockets.remove(this); //从set中删除
subOnLineCount(); //在线数-1
System.out.println("有一个连接关闭!当前在线人数为:" + getOnLineCount());
}
/*
收到客户端发送的消息后调用的方法
@param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session){
System.out.println("来自客户端的消息:" + message);
//群发消息
for (MyWebSocket item : webSockets){
try {
item.sendMessage(message);
}catch (IOException e){
e.printStackTrace();
}
}
}
/*
发生错误时调用
*/
@OnError
public void one rror(Session session, Throwable error){
System.out.println("发生错误");
error.printStackTrace();
}
/*
实现服务器主动推送
@param message
@throws IOException
*/
public void sendMessage(String message) throws IOException{
this.session.getBasicRemote().sendText(message);
}
/*
群发自定义消息
*/
public static void sendInfo(String message) throws IOException{
for (MyWebSocket item : webSockets){
try {
item.sendMessage(message);
}catch (IOException e){
continue;
}
}
}
/*
获取当前连接人数
*/
public static synchronized int getOnLineCount(){
return onLineCount;
}
/*
连接数+1
*/
public static synchronized void addOnLineCount(){
MyWebSocket.onLineCount++;
}
/*
连接数-1
*/
public static synchronized void subOnLineCount(){
MyWebSocket.onLineCount--;
}
}
4、前端页面编写------前端往后端推送消息
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My WebSocket</title>
</head>
<body>
<h1>welcome</h1>
<input id="text" type="text" />
<button onclick="send()">Send</button>
<button onclick="closeWebSocket()">Close</button>
<div id="message"></div>
</body>
<script type="text/javascript">
var webSocket = null;
//判断当前的浏览器是否支持WebSocket
if ('WebSocket' in window){
webSocket = new WebSocket("ws://localhost:8080/websocket")
}else {
alert("Not Support WebSocket")
}
//连接错误时的回调方法
webSocket.onerror = function () {
setMessageInnerHTML("error")
}
//连接成功的回调方法
webSocket.onopen = function () {
setMessageInnerHTML("open")
}
//接收到消息的回调方法
webSocket.onmessage = function () {
setMessageInnerHTML(event.data)
}
//连接关闭的回调方法
webSocket.onclose = function () {
setMessageInnerHTML("close")
}
//监听窗口关闭时间,当窗口关闭时,主动去关闭websocket连接,防止丽娜姐还没断开就关闭窗口,server端会抛异常
window.onbeforeunload = function () {
webSocket.close()
}
//将消息显示到网页上
function setMessageInnerHTML(innerHTML) {
document.getElementById('message').innerHTML += innerHTML + '/<br>'
}
//关闭连接
function closeWebSocket() {
webSocket.close()
}
//发送消息
function send() {
var message = document.getElementById('text').value;
webSocket.send(message)
}
</script>
</html>
5、前端往后端发送消息测试
6、后端往前端推送消息测试
请求上面那个路径,查看前端