> 文章列表 > SpringBoot中使用WebSocket Demo

SpringBoot中使用WebSocket Demo

SpringBoot中使用WebSocket Demo

大概目录结构

 

依赖只引入了JSP 和SpringBoot整合WebSocket   Spring Web

 

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><script src="${pageContext.request.contextPath}/js/jquery.min.js"></script><title>SpringBoot+WebSocket+JSP</title>
</head><body style="margin: 45px;"><h4>在线聊天室</h4><div class="form-group"><label for="content"></label><textarea id="content" readonly="readonly" cols="80" rows="15"></textarea></div><div class="form-group" style="margin-top: 8px"><textarea id="message" cols="80" rows="5" placeholder="请输入消息"></textarea><div style="margin-top: 10px"><button id="toSend" class="btn btn-info">发送</button><button id="user_exit" class="btn btn-danger">离开</button><input id="username" value="${username}" style="display: none"></div></div><script type="text/javascript">$(function () {var ws;if ("WebSocket" in window) {var baseUrl = 'ws://localhost:8080/websocket/';var userName = $('#username').val();ws = new WebSocket(baseUrl + userName);// 连通之后的回调事件,建立连接ws.onopen = function () {console.log("建立 websocket 连接...");};// 接收后台服务端的消息ws.onmessage = function (event) {$('#content').append(event.data + '\\n\\n');console.log("接收到服务端发送的消息..." + event.data + '\\n');};ws.onerror = function (event) {console.log("websocket发生错误..." + event + '\\n');}// 连接关闭的回调事件ws.onclose = function () {$('#content').append('[' + userName + '] 已离开!');console.log("关闭 websocket 连接...");};} else {// 浏览器不支持 WebSocketalert("您的浏览器不支持WebSocket!");}// 客户端发送消息到服务器$('#toSend').click(function () {sendMsg();});$(document).keyup(function (event) {// 回车键事件if (event.keyCode == 13) {sendMsg();}});// 发送消息function sendMsg() {//websocket发送消息ws.send($('#message').val());$('#message').val("");}// 退出$('#user_exit').click(function () {if (ws) {ws.close();}});});</script>
</body>
</html>

控制器

@Controller
public class ChatController {private AtomicInteger idProducer = new AtomicInteger();@RequestMapping("/")public String index(Model model) {model.addAttribute("username","user" + idProducer.getAndIncrement());return "index";}
}

配置类

@EnableWebSocket //启用WebSocket支持
@Configuration //表示配置类
public class WebSocketConfig {/* 配置ServerEndpointExporter的bean 该Bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint*/@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}
/* 说明:* 1、@ServerEndpoint注解中指定WebSocket协议的地址;* 2、@OnOpen、@OnMessage、@OnClose、@OnError注解与WebSocket中监听事件对应*/
@Slf4j //lombok jar包,帮我们自动生成一些代码:@Data
@Component
@ServerEndpoint("/websocket/{username}")
public class ChatServerEndpoint {/* 连接建立时触发*/@OnOpenpublic void openSession(@PathParam("username") String username, Session session) {log.info("用户{}登录", username);String message = "用户[" + username + "] 已进入聊天室!";// 发送登录消息给其他人WebSocketUtils.sendMessageAll(message);// 获取当前在线人数,发给自己String onlineInfo = WebSocketUtils.getOnlineInfo();//发送消息WebSocketUtils.sendMessage(session, onlineInfo);// 添加自己到map中WebSocketUtils.CLIENTS.put(username, session);}/* 客户端接收服务端数据时触发*/@OnMessagepublic void onMessage(@PathParam("username") String username, String message) {log.info("发送消息:{}, {}", username, message);//广播,把消息同步给其他客户端WebSocketUtils.sendMessageAll("[" + username + "] : " + message);}/* 连接关闭时触发*/@OnClosepublic void onClose(@PathParam("username") String username, Session session) {// 当前的Session移除某个用户WebSocketUtils.CLIENTS.remove(username);// 离开消息通知所有人WebSocketUtils.sendMessageAll("[" + username + "] 已离开!");try {//关闭WebSocket Session会话session.close();log.info("{} 已退出, onclose", username);} catch (IOException e) {e.printStackTrace();log.error("onClose error", e);}}/* 通信发生错误时触发*/@OnErrorpublic void onError(Session session, Throwable throwable) {try {//关闭WebSocket Session会话session.close();} catch (IOException e) {e.printStackTrace();log.error("onError Exception", e);}log.info("Throwable msg " + throwable.getMessage());}
}
public final class WebSocketUtils {private static final Logger logger = LoggerFactory.getLogger(WebSocketUtils.class);/* 存储WebSocket session* <p>* 用户名为key,WebSocket Session对象为value*/public static final Map<String, Session> CLIENTS = new ConcurrentHashMap<>();/* 使用连接发送数据 @param session 用户session* @param message 发送内容*/public static void sendMessage(Session session, String message) {if (session == null) {return;}final RemoteEndpoint.Basic basic = session.getBasicRemote();if (basic == null) {return;}try {//发送basic.sendText(message);} catch (IOException e) {e.printStackTrace();logger.error("sendMessage IOException ", e);}}/* 发送消息给其他所有人 @param message*/public static void sendMessageAll(String message) {CLIENTS.forEach((sessionId, session) -> sendMessage(session, message));}/* 获取所有在线用户*/public static String getOnlineInfo() {Set<String> userNames = CLIENTS.keySet();if (userNames.size() == 0) {return "当前无人在线...";}return CLIENTS.keySet().toString() + "在线";}
}