消息推送之Websocket
来源:互联网 发布:腾鹰软件 编辑:程序博客网 时间:2024/05/29 02:25
WebSocket是html5新增加的特性之一,可以实现客户端和服务器彼此之间相互通信,也可以实现跨域通信,目前大部分主流浏览器都支持,iE浏览器需要10版本以上。
需求:公司项目有一个报警模块,当后台接收到报警消息之后,需要及时的推送到浏览器上,显示给用户。
一:导入WebSocket的maven依赖:
<dependency><groupId>javax.websocket</groupId><artifactId>javax.websocket-api</artifactId><version>1.0</version><scope>provided</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-websocket</artifactId><version>4.1.4.RELEASE</version></dependency>
二:建立WebSocket入口
创建一个类实现WebSocketConfigurer接口并继承WebMvcConfigurerAdapter,这个方法中可以配置websocket入口,指定允许访问的域、handler、和拦截器.
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import org.springframework.web.socket.config.annotation.EnableWebSocket;import org.springframework.web.socket.config.annotation.WebSocketConfigurer;import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;import org.springframework.web.socket.handler.TextWebSocketHandler;@Configuration@EnableWebMvc@EnableWebSocketpublic class SpringWebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{ public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {//注册websocket通道,指定handler和拦截器 registry.addHandler(webSocketHandler(),"/websocket/socketServer").addInterceptors(new SpringWebSocketHandlerInterceptor()); registry.addHandler(webSocketHandler(), "/sockjs/socketServer").addInterceptors(new SpringWebSocketHandlerInterceptor()).withSockJS();} @Bean public TextWebSocketHandler webSocketHandler(){ //核心处理handler类 return new SpringWebSocketHandler(); }}
三:编写拦截器
import java.util.Map;import javax.servlet.http.HttpSession;import org.springframework.http.server.ServerHttpRequest;import org.springframework.http.server.ServerHttpResponse;import org.springframework.http.server.ServletServerHttpRequest;import org.springframework.web.socket.WebSocketHandler;import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;public class SpringWebSocketHandlerInterceptor extends HttpSessionHandshakeInterceptor{@Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception { if (request instanceof ServletServerHttpRequest) { /* ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; HttpSession session = servletRequest.getServletRequest().getSession(false); if (session != null) { //使用userName区分WebSocketHandler,以便定向发送消息 String userName = (String) session.getAttribute("username"); if (userName==null) { userName="default-system"; } attributes.put("WEBSOCKET_USERNAME",userName); } */ } return true; } public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) { super.afterHandshake(request, response, wsHandler, ex); }}
四:编写handler
import java.io.IOException;import java.util.ArrayList;import org.apache.log4j.Logger;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;public class SpringWebSocketHandler extends TextWebSocketHandler{ private static final ArrayList<WebSocketSession> users; private static Logger logger = Logger.getLogger(SpringWebSocketHandler.class); static { users = new ArrayList<WebSocketSession>(); } /** * 连接成功时候,会触发页面上onopen方法 */ public void afterConnectionEstablished(WebSocketSession session) throws Exception { users.add(session); //这块会实现自己业务,比如,当用户登录后,会把离线消息推送给用户 TextMessage returnMessage = new TextMessage("推送测试"); // session.sendMessage(returnMessage); //sendMessageToUsers(new TextMessage("hahhaa")); } /** * 关闭连接时触发 */ public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { logger.debug("websocket connection closed......"); String username= (String) session.getAttributes().get("WEBSOCKET_USERNAME"); System.out.println("用户"+username+"已退出!"); users.remove(session); System.out.println("剩余在线用户"+users.size()); } /** * js调用websocket.send时候,会调用该方法 */ protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { super.handleTextMessage(session, message); } /** * 发生错误时触发 */ public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { if(session.isOpen()){ session.close(); } logger.debug("websocket connection closed......"); users.remove(session); } public boolean supportsPartialMessages() { return false; } /** * 使用这个方法像客户端某个在线用户发送消息 * * @param userName * @param message */ public void sendMessageToUser(String userName, TextMessage message) { for (WebSocketSession user : users) { if (user.getAttributes().get("WEBSOCKET_USERNAME").equals(userName)) { try { if (user.isOpen()) { user.sendMessage(message); } } catch (IOException e) { e.printStackTrace(); } break; } } } /** * 使用这个方法像客户端所有在线用户发送消息 * * @param message */ public void sendMessageToUsers(TextMessage message) { for (WebSocketSession user : users) { try { if (user.isOpen()) { user.sendMessage(message); } } catch (IOException e) { e.printStackTrace(); } } }}
五:客户端代码
<!--导入js文件--><script type="text/javascript"src="http://cdn.bootcss.com/sockjs-client/1.1.1/sockjs.js"></script><script type="text/javascript">function wsPath() {var pathName = window.document.location.pathname;var host = window.location.host;var projectName = pathName.substring(0,pathName.substr(1).indexOf('/') + 1);return (host + projectName);}wsPath = wsPath();var websocket = null;if ('WebSocket' in window) {websocket = new WebSocket("ws://" + wsPath + "/websocket/socketServer");} else if ('MozWebSocket' in window) {websocket = new MozWebSocket("ws://" + wsPath+ "/项目名称/websocket/socketServer");} else {websocket = new SockJS("http://" + wsPath+ "/项目名称/sockjs/socketServer");}websocket.onmessage = onMessage;websocket.onope = onOpen;websocket.onerror = onError;websocket.onclose = onClose;function onOpen() {}function onMessage(evt) {//这里evt就是推送给过来的消息}function onError() {websocket.close();}function onClose() {}window.close = function() {websocket.onclose();}</script>
六:测试
import org.springframework.context.annotation.Bean;import org.springframework.web.socket.TextMessage;public class Test {@Bean// 这个注解会从Spring容器拿出Beanpublic static SpringWebSocketHandler infoHandler() {return new SpringWebSocketHandler();}public static void main(String[] args) {infoHandler().sendMessageToUsers(new TextMessage("哈哈,测试小哥"));}}
结束!!!!!
阅读全文
0 0
- 消息推送之Websocket
- Websocket消息推送平台
- websocket消息推送
- WebSocket与消息推送
- WebSocket与消息推送
- WebSocket与消息推送
- java websocket消息推送
- webSocket 消息推送
- WebSocket与消息推送
- WebSocket与消息推送
- WebSocket与消息推送
- WebSocket与消息推送
- WebSocket与消息推送
- WebSocket与消息推送
- WebSocket与消息推送
- 使用WebSocket推送服务器消息
- netty websocket 后台消息推送
- websocket实现android消息推送
- 运放 输入失调电压
- 属性动画 小球从左上角到右下角运动
- JS实现栈结构
- JAVA集合类总结
- 静态路由的配置
- 消息推送之Websocket
- struts2 拦截器
- 顺序表的逆置
- java 枚举类的简单例子
- Mysql命令大全
- 安卓向SD卡存储数据时java.io.FileNotFoundException:(Permission denied)
- 简单版购物车功能实现
- 【奇奇怪怪的bug】谷歌浏览器控制台无法输出
- 回文数