WebSocket
Sockjs
Stoup (消息订阅发布)
添加依赖
<!-- 添加依赖 --> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>${servlet.version}</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>${jackson.version}</version> </dependency> </dependencies>
全局类
UserController
package edu.nf.ws.controller; import edu.nf.ws.controller.vo.ResponseVO; import edu.nf.ws.entity.Users; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpSession; /** * @Author Eric * @Date 2018/12/6 */ @RestController public class UserController { @PostMapping("/userLogin") public ResponseVO login(Users user, HttpSession session){ //验证用户 //.... //验证成功后将用户放进会话作用域 session.setAttribute("user",user); ResponseVO responseVO = new ResponseVO(); responseVO.setCode(HttpStatus.OK.value()); responseVO.setData("index.html"); return responseVO; } }
ServerEndpointHandler
package edu.nf.ws.websocket; import edu.nf.ws.entity.Users; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * @Author Eric * @Date 2018/12/6 * websocket服务端 */ public class ServerEndpointHandler extends TextWebSocketHandler { /** * 维护一个用户列表(key存放用户名,value存放每个用户的WebSocketSession) */ private static Map<String, WebSocketSession> users = new ConcurrentHashMap<>(); /** * 客户端建立连接之后执行此方法(onOpen) * @param session 每当客户端连接后,容器会为其创建一个Session对象, * 这个对象在Spring中就是WebSpcketSession * @throws Exception */ @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { System.out.println("客户端建立了连接..."); //获取用户名,getAttributes方法得到的是一个Map //这个map里面存放了握手拦截器将HttpSession作用域拷贝过去的数据 Users user = (Users)session.getAttributes().get("user"); //将用户的session保存到用户列表中 users.put(user.getUserName(),session); } /** * 每当客户端发送信息时执行此方法(onmessage) * @param session * @param message TextMessage对象表示接受客户端的文本信息对象 * 它的getPayload方法将获得具体消息内容 * @throws Exception */ @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { System.out.println("接收客户端消息..."+message); //获取用户名 Users sendUser = (Users)session.getAttributes().get("user"); //群发消息 for (String userName : users.keySet()) { //重新构建一个TextMessage对象 TextMessage newMessage = new TextMessage(sendUser.getUserName()+":"+message.getPayload()); //发送所有人 users.get(userName).sendMessage(newMessage); } } /** * 客户端关闭或者断开连接时执行此方法(onclose) * @param session * @param status * @throws Exception */ @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { System.out.println("客户端断开连接..."); session.close(); } }
index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>发送内容</title> </head> <body> <div align="center"> <div class="content-padded" > <div id="content"></div> </div> <div class="item-input"> <input type="text" id="msg" placeholder="输入内容.."> </div> <div class="col-100"> <p><a class="button" id="btn" style="200px">send</a></p> </div> </div> <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script> <link rel="stylesheet" href="//g.alicdn.com/msui/sm/0.6.2/css/sm.min.css"> <script type='text/javascript' src='//g.alicdn.com/sj/lib/zepto/zepto.min.js' charset='utf-8'></script> <script type='text/javascript' src='//g.alicdn.com/msui/sm/0.6.2/js/sm.min.js' charset='utf-8'></script> </body> <script> $(function () { var ws = new WebSocket('ws://localhost:8080/websocket'); ws.onmessage = function (event) { $('#content').append(event.data + '<br>'); } $('#btn').on('click',function () { var msg = $('#msg').val(); //发送信息 ws.send(msg); }); }); </script> </html>
login.html
<!DOCTYPE html> <html> <meta charset="utf-8"> <link rel="stylesheet" href="//g.alicdn.com/msui/sm/0.6.2/css/sm.min.css"> <script type='text/javascript' src='//g.alicdn.com/sj/lib/zepto/zepto.min.js' charset='utf-8'></script> <script type='text/javascript' src='//g.alicdn.com/msui/sm/0.6.2/js/sm.min.js' charset='utf-8'></script> <script type="text/javascript" src="js/jquery-3.3.1.min.js"></script> <head> <a class="button button-link button-nav pull-left" href="/demos/card" data-transition='slide-out'> <span class="icon icon-left"></span> 返回 </a> <h1 class="title">我的App</h1> </head> <body> <nav class="bar bar-tab"> <a class="tab-item active" href="#"> <span class="icon icon-home"></span> <span class="tab-label">首页</span> </a> <a class="tab-item" href="#"> <span class="icon icon-me"></span> <span class="tab-label">我</span> </a> <a class="tab-item" href="#"> <span class="icon icon-star"></span> <span class="tab-label">收藏</span> </a> <a class="tab-item" href="#"> <span class="icon icon-settings"></span> <span class="tab-label">设置</span> </a> </nav> <div class="content"> <div class="list-block"> <form id="f1"> <ul> <!-- Text inputs --> <li> <div class="item-content"> <div class="item-inner"> <div class="item-title label">Name</div> <div class="item-input"> <input type="text" name="userName" placeholder="Your name"> </div> </div> </div> </li> <li> <div class="item-content"> <div class="item-inner"> <div class="item-title label">Password</div> <div class="item-input"> <input type="password" name="password" placeholder="password"> </div> </div> </div> </li> </ul> </form> </div> <div class="content-block"> <div class="row"> <div class="col-50"><a href="#" class="button button-big button-fill button-danger">取消</a></div> <div class="col-50"><a href="#" id="btn" class="button button-big button-fill button-success">注册</a></div> </div> </div> </div> </body> <script> $(function(){ $("#btn").on("click",function(){ $.ajax({ type:"post", url:"userLogin", data:$("#f1").serialize(), success:function(result){ if(result.code==200){ location.href=result.data; }else { alert(result.mesage); } } }); }); }); </script> </html>
配置web.xml和dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:dispatcher-servlet.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd"> <context:component-scan base-package="edu.nf.ws"/> <mvc:annotation-driven/> <mvc:default-servlet-handler/> <!--配置WebSocket的handler--> <bean id="serverEndpoint" class="edu.nf.ws.websocket.ServerEndpointHandler"/> <!--配置websocket--> <websocket:handlers> <!--path为websocket连接的url,handler引用我们定义的ServerEndpoint--> <websocket:mapping path="/websocket" handler="serverEndpoint"/> <!--配置HttpSession握手拦截器--> <!--说明:这个握手拦截器会将HttpSession中的数据拷贝到 WebSocketSession的属性中,因此在WebSocket中 也能访问会话作用域的信息--> <websocket:handshake-interceptors> <bean class="org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor"/> </websocket:handshake-interceptors> </websocket:handlers> </beans>