WebSocket是一种协议,用于在Web应用程序和服务器之间建立实时、双向的通信连接。它通过一个单一的TCP连接提供了持久化连接,这使得Web应用程序可以更加实时地传递数据。
具体的就不多说了,不懂的可以自己搜搜看,直接上代码。
<!-- Spring Boot Starter WebSocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.5.3</version>
</dependency>
ws的配置文件
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
/**
* @Author HaoLinXie
* @Date 2024/5/8 10:54
* @ClassName: WebSocketConfig
* @Description: 配置类
* @Version 1.0
*/
@Configuration
public class WebSocketConfig {
/**
* 自动注册使用了@ServerEndpoint注解声明的Websocket endpoint
*
* @return
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
/**
* 通信文本消息和二进制缓存区大小
* 避免对接 第三方 报文过大时,Websocket 1009 错误
* @return
*/
@Bean
public ServletServerContainerFactoryBean createWebSocketContainer() {
ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
// 在此处设置bufferSize
container.setMaxTextMessageBufferSize(10240000);
container.setMaxBinaryMessageBufferSize(10240000);
container.setMaxSessionIdleTimeout(15 * 60000L);
return container;
}
}
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.core.ApplicationContext;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* @Author HaoLinXie
* @Date 2024/5/7 17:06
* @ClassName: WebSocketServer
* @Description: WebSocket
* @Version 1.0
*/
@Slf4j
@Component
@ServerEndpoint(value = "/WebSocketTest")//用于前端连接
public class WebSocketServer {
//Websocket名称
private static String NAME = "WebSocketTest";
//与某个客户端连接会话,需要通过它来给客户端发送数据
private Session session;
private String ip;
//保存所有的ws连接讯息
private static CopyOnWriteArraySet<WebSocketServer> webSockets = new CopyOnWriteArraySet<>();
//心跳报文
private static final String HEARTBEAT_PACKETS = "The heartbeat packets";
//用于获取应用的上下文
private static ApplicationContext applicationContext;
//发送数据的方法
public static void sendMapMessage(String type, Object data) {
for (WebSocketServer webSocketServer : webSockets) {
try {
if (webSocketServer.session.isOpen()) {
JSONObject result = new JSONObject();
result.put("type", type);
result.put("date", data);
webSocketServer.session.getAsyncRemote().sendText(result.toString());
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session) {
try {
this.session = session;
// 加入set中
webSockets.add(this);
System.out.println(NAME + "连接成功!");
System.out.println(NAME + "有新的连接,当前连接数总数为:" + webSockets.size());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
try {
// 从set中删除
webSockets.remove(this);
System.out.println(NAME + "有连接断开,当前连接数总数为:" + webSockets.size());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
*/
@OnMessage
public void OnMessage(String message, Session session) {
if (HEARTBEAT_PACKETS.equals(message)) {
log.debug("[消息订阅] - 心跳.");
return;
}
// TODO 接收前端入参后的业务处理
}
/**
* 发生错误时调用
*/
@OnError
public void OnError(Session session, Throwable error) {
error.printStackTrace();
log.error("[历史数据回放] - WS 异常断开", session, error);
}
/**
* 群发自定义消息
*/
public static void sendInfo(String message, Object data) {
for (WebSocketServer item : webSockets) {
item.sendMapMessage(message, data);
}
}
/**
* 指定会话推送
*
* @param message
*/
public static void sendInfo(Session session, String message, Object data) {
for (WebSocketServer item : webSockets) {
if (null != session && item.session.equals(session)) {
item.sendMapMessage(message, data);
}
}
}
public static void setApplicationContext(ApplicationContext applicationContext) {
WebSocketServer.applicationContext = applicationContext;
}
public static CopyOnWriteArraySet<WebSocketServer> getWebSockerSet() {
return webSockets;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
WebSocketServer that = (WebSocketServer) o;
return Objects.equals(session, that.session);
}
@Override
public int hashCode() {
return Objects.hash(session);
}
}
使用案例
import com.jiurong.webSocket.WebSocketServer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author HaoLinXie
* @Date 2024/5/8 23:54
* @ClassName: TestWSController
* @Description: 模拟使用
* @Version 1.0
*/
@RequestMapping("testWS")
@RestController
public class TestWSController {
@RequestMapping(value = "getWS", method = RequestMethod.GET)
public String getWS() {
//处理要发送的数据逻辑
String data = "我就是要发送的数据";
//这个key是type,如果一个通道要发送多个不同的数据,可以使用type区分
WebSocketServer.sendMapMessage("testWebsocket", data);
return "成功!";
}
}
测试使用:
启动时建立ws连接: ws://ip:端口/路径(你要连接的ws名字)
连接成功,模拟调用http发送ws数据