SpringMVC+WebSocket+H5 Notification实例
来源:互联网 发布:大数据概念股一览 编辑:程序博客网 时间:2024/06/03 16:47
传统的HTTP协议是被动的,单项的即服务器传递信息给客户端,每次发送信息都需要封装HTTP协议中的Headers等相关信息。实时性消息较高的应用场景瓶颈非常明显如聊天室,无法主动获取客户端发送的信息,每次传输数据都需要发送一个完整的HTTP请求,数据传输效率低。
WebSocket其实就是一套新的协议,可以实现Socket编程效果,初次连接的时候初始化一次,只要连接不关闭便可以实现客户端和服务器的实时数据传递。
WebSocket协议是基于HTTP即浏览器的一套新的编程接口,客户端与服务器的连接通过JavaScript编程,页面关闭后连接便失效了,刷新页面会先关闭当前的连接再建立新的连接。
开发工具:
SpringMVC4.0+(spring-websocket包,支持WebSocket编程)
Tomcat 7.0+ (支持WebSocket协议)
实例使用的是SpringMVC4.15+Tomcat7.0.76+JDK1.8
核心代码:
WebSocketInterceptor 拦截器,每次连接时触发。
WebSocketConfig 配置文件,WebSocket实例化。
SocketHandler 业务逻辑处理。
public class WebSocketInterceptor implements HandshakeInterceptor { @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler, Map<String, Object> map) throws Exception { ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request;这里写代码片 String[] str = serverHttpRequest.getServletRequest().getParameterMap().get("id"); map.put("id", str[0]); return true; } @Override public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) { }}ide public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler, Map<String, Object> map) throws Exception { ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request; String[] str = serverHttpRequest.getServletRequest().getParameterMap().get("id"); map.put("id", str[0]); return true; } @Override public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) { }}@Configuration@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "/socketHandler").addInterceptors(new WebSocketInterceptor()).setAllowedOrigins("*"); } //@Bean public WebSocketHandler myHandler() { return new SocketHandler(); }}@Configuration@EnableWebSocketpublic class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(myHandler(), "/socketHandler").addInterceptors(new WebSocketInterceptor()).setAllowedOrigins("*"); } //@Bean public WebSocketHandler myHandler() { return new SocketHandler(); }}@Servicepublic class SocketHandler extends TextWebSocketHandler { //在线用户列表(适用于单用户多点) private static final Map<Integer, List<WebSocketSession>> users; static { users = new HashMap<>(); } @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { System.out.println("成功建立连接"); Integer userId = getClientId(session); List<WebSocketSession> list = users.get(userId); if (null == list){ list = new ArrayList<>(); list.add(session); users.put(userId, list); } else list.add(session); } /*** * 接收客户端信息 */ @Override public void handleTextMessage(WebSocketSession session, TextMessage message) { System.out.println(message.getPayload()); } /** * 发送信息给指定用户 * @param userloginid 用户标识 * @param message * @return */ public void sendMessageToUser(Integer userloginid, TextMessage message) { if (users.get(userloginid) == null) return; List<WebSocketSession> list = users.get(userloginid); for(int i=0;i<list.size();i++){ WebSocketSession session = list.get(i); if (!session.isOpen()) continue; try { session.sendMessage(message); } catch (IOException e) { e.printStackTrace(); } } } /** * 广播信息 * @param userloginid 用户标识 * @param message * @return */ public void sendMessageToAllUser(Integer userloginid,TextMessage message) { Set<Integer> clientIds = users.keySet(); for (Integer clientId : clientIds) { if(clientId != userloginid) sendMessageToUser(clientId,message); } } /** * 广播信息 * @param message * @return */ public void sendMessageToAllUsers(TextMessage message) { Set<Integer> clientIds = users.keySet(); for (Integer clientId : clientIds) { sendMessageToUser(clientId,message); } } /*** * 关闭连接 * @param id * @param session */ public void remove(int id,WebSocketSession session){ if (users.get(id) == null) return; List<WebSocketSession> list = users.get(id); Optional<WebSocketSession> optional = list.stream().filter(m->m.equals(session)).findFirst(); if(optional.isPresent()) list.remove(optional.get()); if(null == list || list.size()==0) users.remove(id); } /*** * 出错是执行,关闭浏览器界面会执行该方法,并自动关闭session */ @Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { if (session.isOpen()) { session.close(); } remove(getClientId(session),session); } /*** * 关闭session时执行 */ @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { if (session.isOpen()) { session.close(); } remove(getClientId(session),session); } @Override public boolean supportsPartialMessages() { return false; } /** * 获取用户标识 * @param session * @return */ private Integer getClientId(WebSocketSession session) { return Integer.parseInt(session.getAttributes().get("id").toString()); }}
HTML代码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><%@ page isELIgnored="false"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>WebSocket</title> </head> <body> <button>socket连接</button> <script src="${pageContext.request.contextPath}/js/jquery-2.1.1.js"></script> <script type="text/javascript"> $(function() { $("button").click(function(){ if (typeof WebSocket == 'undefined') alert("浏览器不支持相关特性,请更换为谷歌,UC浏览器。") else{ //WebSocket客户端建立,生命周期为当前页面。 var ws = new WebSocket("ws://localhost:8123/websocket/socketHandler?id=4") ws.onopen = function () { console.log("onpen"); ws.send("客户端发送消息"); } //页面关闭便会触发 ws.onclose = function () { console.log("onclose"); } ws.onmessage = function (msg) { console.log(msg.data); var message = msg.data.split(","); //浏览器支持Notification,并允许接收通知 if($.notificationHandler.requestPermission()) $.notificationHandler.showNotification('${pageContext.request.contextPath}/images/11.png',message[0],message[1]); } } }); }) </script></body></html>
本实例中运用到了H5的Notification发送通知,相关代码已封装到JS文件里了,便不多叙述了。
下载地址:http://download.csdn.net/download/lishengko/9998130
阅读全文
0 0
- SpringMVC+WebSocket+H5 Notification实例
- H5 websocket C# server
- H5笔记-WebSocket协议
- H5的 WebSocket
- H5——webSocket
- 【WebSocket】WebSocket经典实例
- websocket实例
- WebSocket实例
- 基于WebSocket实现的Android和H5聊天通讯实例【附效果图附所有源码】
- Notification实例
- 初识标准H5的WebSocket
- springMVC整合websocket实践
- SpringMVC整合WebSocket
- SpringMVC+WebSocket整合
- Springmvc+WebSocket整合
- springMVC结合websocket小结
- SpringMVC整合WebSocket
- Spring+SpringMVC+WebSocket
- 各种B树之比较
- C# gridview 显示两位小数
- 十年编程,是人玩技术还是技术玩人?
- Java并发编程之Lock
- Linux下静态库.a与.so库文件的生成与使用
- SpringMVC+WebSocket+H5 Notification实例
- Spring AOP底层实现原理
- jdbcBaseDao封装模板
- java并发编程的艺术(六)-----AQS
- 同一个ImageView显示不同的图片--->level-list
- QT5学习 QFileSystemModel
- 累累白骨下,共享单车的困局
- 思考与学习方法
- [bzoj2083][Poi2010]Intelligence test(二分)