Spring4.0 + 实现简单的聊天
2016-01-21 11:47
495 查看
最近因为要在项目中加入在线聊天功能,所以想到了spring 自带的WebSocket,之前有听说,但是一直没有研究过,去网上一搜感觉乱七八糟,梳理了一整天,终于作出了一个简单的Demo。
Spring 版本使用4.0 以上 其他没有任何要求
标红色的是需要加上去的,其他的都是一些web的基本配置,不做介绍。
1、WebSocket 配置
配置WebSocketConfig,相当于注册一个服务(下面代为是 创建一个请求路径为“/echo” 的服务)。
这里 涉及到两个类 WebSocketHander 和 HandshakeInterceptor 是下面要实现的连个类,一个用来连接Socket连接,一个用来处理消息。至于"/echo" 这个路径是 前端用来请求websocket 连接的路径,
代码注释 比较详细,服务在接到请求后,交给Handle 处理。
拦截器创建后,服务端的处理基本上就完成了。下面是前端的处理。
WebSocket 对象的应用:分别是:创建,连接,关闭,接受消息,发送消息,出错处理
var websocket = new WebSocket("ws://127.0.0.1:8080/echo");
websocket.onopen = function (evnt) { $("#tou").html("链接服务器成功!") };
websocket.onmessage = function (evnt) { //接受消息处理 };
websocket.onerror = function (evnt) { //出错处理 };
websocket.onclose = function (evnt) { //关闭连接 }
websocket.send(message); //发送消息
直接访问页面,就可以了。
![](https://img-blog.csdn.net/20160121123240499?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
作者这里使用的是谷歌浏览器,没有在其他版本浏览器上测试。
1、环境
Spring MVC + Tomcate (本人使用 MyEclipse2014 开发)Spring 版本使用4.0 以上 其他没有任何要求
2、配置
web.xml<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:websocket="http://www.springframework.org/schema/websocket" 这 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd" id="WebApp_ID" version="3.1"> <display-name>spring_demo</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext*.xml</param-value> </context-param> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>detectAllHandlerExceptionResolvers</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>*.xls</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <filter> <filter-name>HiddenHttpMethodFilter</filter-name> <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class> </filter> <filter-mapping> <filter-name>HiddenHttpMethodFilter</filter-name> <servlet-name>spring</servlet-name> </filter-mapping> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
标红色的是需要加上去的,其他的都是一些web的基本配置,不做介绍。
3、Spring 对于webSocket的处理
1、WebSocket 配置
配置WebSocketConfig,相当于注册一个服务(下面代为是 创建一个请求路径为“/echo” 的服务)。import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; /** * WebSocket 配置 * @author yanbumo */ @Configuration @EnableWebMvc @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer{ @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { //registry.addHandler(new WebSocketHander(),"/echo").addInterceptors(new HandshakeInterceptor()); //支持websocket 的访问链接 //registry.addHandler(new WebSocketHander(),"/sockjs/echo").addInterceptors(new HandshakeInterceptor()).withSockJS(); //SockJS的访问链接 registry.addHandler(new WebSocketHander(),"/echo").addInterceptors(new HandshakeInterceptor()); } }
这里 涉及到两个类 WebSocketHander 和 HandshakeInterceptor 是下面要实现的连个类,一个用来连接Socket连接,一个用来处理消息。至于"/echo" 这个路径是 前端用来请求websocket 连接的路径,
<strong style="background-color: rgb(255, 255, 255);">websocket = new WebSocket("ws://127.0.0.1:8080/echo");</strong>
2、WebSocketHander 处理消息
import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.springframework.web.socket.CloseStatus; 4000 import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketMessage; import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.handler.TextWebSocketHandler; public class WebSocketHander extends TextWebSocketHandler{ /** * 存放所有连接的用户 */ private static final Map<String,WebSocketSession> users = new HashMap<String, WebSocketSession>(); /** * 初次链接成功执行 */ @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { System.out.println(session.getId() + " 上线"); sendMessageToUsers(new TextMessage(session.getId() + " 上线")); users.put(session.getId(), session); } /** * 接受消息处理消息 */ @Override public void handleMessage(WebSocketSession from, WebSocketMessage<?> message) throws Exception { String fromMsg = message.getPayload().toString(); if(fromMsg.contains(" To ")){ String targetId = fromMsg.split(" To ")[1].trim(); String msg = fromMsg.split(" To ")[0]; WebSocketSession target = users.get(targetId); target.sendMessage(new TextMessage("来自" + from.getId() + ":" + msg.split(" To ")[0])); from.sendMessage(new TextMessage("我:" + msg)); }else{ sendMessageToUsers(new TextMessage("来自" + from.getId() + ":" + fromMsg)); } } /** * 错误处理 */ @Override public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception { if(webSocketSession.isOpen()){ webSocketSession.close(); } users.remove(webSocketSession); } /** * 关闭连接 */ @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { System.out.println(session.getId() + " 下线"); sendMessageToUsers(new TextMessage(session.getId() + " 下线")); users.remove(session); } /** * 支持文件传输 */ @Override public boolean supportsPartialMessages() { return false; } /** * 给所有用户推送 */ public void sendMessageToUsers(TextMessage message) throws IOException { Set<String> ids = users.keySet(); for (String id : ids) { WebSocketSession user = users.get(id); user.sendMessage(message); } } /** * 给目标发送消息 */ public void setMsg(WebSocketSession session,String msg) throws IOException{ session.sendMessage(new TextMessage(msg)); } }
代码注释 比较详细,服务在接到请求后,交给Handle 处理。
3、HandshakeInterceptor 拦截器
import java.util.Map; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.socket.WebSocketHandler; /** * @author yanbumo */ public class HandshakeInterceptor implements org.springframework.web.socket.server.HandshakeInterceptor { //进入hander之前的拦截 @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception { return true; } @Override public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) { } }
拦截器创建后,服务端的处理基本上就完成了。下面是前端的处理。
4、前台页面
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <!-- <script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script> --> <!-- 新 Bootstrap 核心 CSS 文件 --> <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css"> <!-- 可选的Bootstrap主题文件(一般不用引入) --> <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap-theme.min.css"> <!-- jQuery文件。务必在bootstrap.min.js 之前引入 --> <script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script> <!--<script type="text/javascript" src="js/jquery-1.7.2.js"></script>--> <!-- 最新的 Bootstrap 核心 JavaScript 文件 --> <script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script> <title>webSocket测试</title> <script type="text/javascript"> $(function(){ var websocket; /* if ('WebSocket' in window) { alert("WebSocket"); websocket = new WebSocket("ws://127.0.0.1:8080/echo"); } else if ('MozWebSocket' in window) { alert("MozWebSocket"); websocket = new MozWebSocket("ws://echo"); } else { alert("SockJS"); } */ //websocket = new SockJS("http://127.0.0.1:8080/sockjs/echo"); websocket = new WebSocket("ws://127.0.0.1:8080/echo"); websocket.onopen = function (evnt) { $("#tou").html("链接服务器成功!") }; websocket.onmessage = function (evnt) { $("#msg").html($("#msg").html() + "<br/>" + evnt.data); }; websocket.onerror = function (evnt) { }; websocket.onclose = function (evnt) { $("#tou").html("与服务器断开了链接!") } $('#send').bind('click', function() { send(); }); function send(){ if (websocket != null) { var message = document.getElementById('message').value; websocket.send(message); } else { alert('未与服务器链接.'); } } }); </script> </head> <body> <div class="page-header" id="tou"> webSocket及时聊天Demo程序 </div> <div class="well" id="msg"> </div> <div class="col-lg"> <div class="input-group"> <input type="text" class="form-control" placeholder="发送信息..." id="message"> <span class="input-group-btn"> <button class="btn btn-default" type="button" id="send" >发送</button> </span> </div> </div> </body> </html>
WebSocket 对象的应用:分别是:创建,连接,关闭,接受消息,发送消息,出错处理
var websocket = new WebSocket("ws://127.0.0.1:8080/echo");
websocket.onopen = function (evnt) { $("#tou").html("链接服务器成功!") };
websocket.onmessage = function (evnt) { //接受消息处理 };
websocket.onerror = function (evnt) { //出错处理 };
websocket.onclose = function (evnt) { //关闭连接 }
websocket.send(message); //发送消息
直接访问页面,就可以了。
4、结果演示
作者这里使用的是谷歌浏览器,没有在其他版本浏览器上测试。
相关文章推荐
- 2015-2016网页设计趋势分析 Web Design of Trends
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- Spring整合Quartz(JobDetailBean方式)
- Spring整合Quartz(JobDetailBean方式)
- 模拟Spring的简单实现
- spring+html5实现安全传输随机数字密码键盘
- Spring中属性注入详解
- SpringMVC框架下JQuery传递并解析Json格式的数据是如何实现的
- struts2 spring整合fieldError问题
- spring的jdbctemplate的crud的基类dao
- 读取spring配置文件的方法(spring读取资源文件)
- Spring Bean基本管理实例详解
- java实现简单美女拼图游戏
- 详解Java的Spring框架中的事务管理方式
- 解析Java的Spring框架的BeanPostProcessor发布处理器
- Java开发框架spring实现自定义缓存标签
- java基本教程之线程休眠 java多线程教程
- JSP开发中在spring mvc项目中实现登录账号单浏览器登录