1. 基础框架的搭建
1.1 导包
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>5.3.27</version> </dependency><!--json依赖包--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.58</version> </dependency>
1.2 要一个WebSocket的配置
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.socket.server.standard.ServerEndpointExporter; /** * 开启WebSocket支持 * @author */ @Configuration public class WebSocketConfig { @Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }
1.3 要一个WebSocke的服务类
import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import org.springframework.web.bind.annotation.RestController; //这里的/webSocket/{id}/{name}只是拦截的url,不一定要是这个,你写/aaa也是行的 @ServerEndpoint("/webSocket/{id}/{name}") @RestController public class TestWebSocket { // 用来记录当前连接数的变量 private static volatile int onlineCount = 0; // 用来存放每个客户端对应的WebSocket对象 private static Map<String, TestWebSocket> webSocketSet = new ConcurrentHashMap<String, TestWebSocket>(); // 与某个客户端的连接会话,需要通过它来与客户端进行数据收发 private Session session; private String username; /连接成功建立的回调方法 @OnOpen public void onOpen(Session session, @PathParam("id") long id, @PathParam("name") String name) throws Exception { this.session = session; webSocketSet.put(name,this); System.out.println("已连接"); } //连接关闭的回调方法 @OnClose public void onClose() { webSocketSet.remove(username); } //接收到消息的回调方法 @OnMessage public void onMessage(String message, Session session) { try { //接受到客户端信息后,立即回复“我是服务器,收到数据了” sendMessage("你个扑街"); } catch (Exception e) { } } // 连接失败 @OnError public void onError(Session session, Throwable error) { } // 发送消息 public void sendMessage(String message) throws IOException { for (TestWebSocket item : webSocketSet.values()) { item.session.getAsyncRemote().sendText(message); } } public static synchronized int getOnlineCount() { return onlineCount; } // 连接数加一 public static synchronized void addOnlineCount() { TestWebSocket.onlineCount++; } // 连接数减一 public static synchronized void subOnlineCount() { TestWebSocket.onlineCount--; } }
2. 应用
2.1 后端推送消息,一般用于boss被击杀,通知全服,打个比方
步骤是这样的,搭好基础框架后,用WebSocket连接前后端,我的前端用的是Apifox创建WebSocket的接口,输入ws://127.0.0.1:8015/webSocket/1/2,后面1、2随便写;后端接口在WebSocket服务类上;连接好了以后调用消息发送;创建好WebSocket连接后,自己再写个http接口,当调用这个接口时,在接口方法里面加一个WebSocket消息发送,这样每次调用http接口就会从后端发消息给WebSocket接口前端
2.1.1 controller层
@RestController @RequestMapping("/all") public class WebSocketController { @Autowired private WebSocketService webSocketService; @PostMapping("/add") public void add(@RequestBody MessageForm messageForm){ webSocketService.add(messageForm); } }
2.1.2 service层
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.xiejunhu.message.form.MessageForm; import org.xiejunhu.message.mapper.WebSocketMapper; import org.xiejunhu.message.controller.TestWebSocket; import org.xiejunhu.message.service.WebSocketService; @Service public class WebSocketServiceImpl implements WebSocketService { @Autowired private TestWebSocket testWebSocket; @Autowired private WebSocketMapper webSocketMapper; @Override public void add(MessageForm messageForm) { messageForm.setId("123"); // 先新增到数据库 webSocketMapper.add(messageForm); // 再从数据库查,也可直接用前端传进来的值 messageForm.getMessage() 发给WebSocket接口 MessageForm list = webSocketMapper.list(messageForm.getMessage()); try { // 在这里做调发送消息的方法将消息发送给前端 testWebSocket.sendMessage("这是数据库里面查出来的消息:"+list.getMessage()); } catch (Exception e) { e.printStackTrace(); } } }