Java web项目使用webSocket
Posted 大雄
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java web项目使用webSocket相关的知识,希望对你有一定的参考价值。
前端:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; String ppp = request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP \'MyJsp.jsp\' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <script src="baseui/js/plugins/jquery.js"></script> </head> <script> function keepalive(ws) { var device = new Object(); // device.deviceIds = $(\'#msgText\').val(); device.optType = \'hb\'; var t = JSON.stringify(device); ws.send(t); } var websocket; if (\'WebSocket\' in window) { websocket = new WebSocket("ws://<%=ppp%>/app/indexConfig/indexConfigWebSocket.do"); } else if (\'MozWebSocket\' in window) { websocket = new MozWebSocket("ws://<%=ppp%>/IBMS/point/webSocketServer.do"); } else { websocket = new SockJS("http://<%=ppp%>/IBMS/sockjs/webSocketServer.do"); } websocket.onopen = function (evnt) { var old = $("#msgcount").html(); $("#msgcount").html(old + "</br><font color=\'green\'>" + "onopen 方法" + "</font>"); var old = $("#msgcount").html(); $("#msgcount").html(old + "</br>ws URL:<font color=\'green\'>" + "ws://<%=ppp%>/app/indexConfig/indexConfigWebSocket.do" + "</font>"); setInterval(function () { keepalive(websocket) }, 3000); }; websocket.onmessage = function (evnt) { var old = $("#msgcount").html(); $("#msgcount").html(old + "</br>(<font color=\'red\'>" + evnt.data + "</font>)"); $("#msgcount").scrollTop($("#msgcount")[0].offsetHeight); }; websocket.onerror = function (e) { for (var p in e) { var old = $("#msgcount").html(); $("#msgcount").html(old + "</br>onerror 方法:<font color=\'green\'>" + p + "=" + e[p] + "</font>"); } }; websocket.onclose = function (evnt) { var old = $("#msgcount").html(); $("#msgcount").html(old + "</br>onclose 方法:<font color=\'green\'>" + "onclose" + "</font>"); } function send() { var device = new Object(); //device = {"data":[{"statisticsId":"设备1","statisticsTypeId":"1","statisticsData":"dt1"}, {"statisticsId":"报警1","statisticsTypeId":"2","statisticsData":"dt1"}, {"statisticsId":"点位1","statisticsTypeId":"3","statisticsData":"po9884"}, {"statisticsId":"属性1","statisticsTypeId":"4","statisticsData":"st32,sv91"}], "optType":""}; var t = $(\'#msgText\').val(); //var t = JSON.stringify(device); console.log(t) var old = $("#msgcount").html(); $("#msgcount").html(old + "</br>请求报文:<font color=\'blue\'>" + t + "</font>") websocket.send(t); if (true)return; var param = new Array(); var point = new Object(); point.pointId = \'1\'; var point2 = new Object(); point2.pointId = \'2\'; point2.newValue = \'789\'; var json = JSON.stringify(point); var json2 = JSON.stringify(point2); param[0] = point; param[1] = point2; var t = JSON.stringify(param); t = eval(t); var arrParam = JSON.stringify(t); websocket.send(arrParam); } function pause() { var device = new Object(); device.deviceIds = $(\'#msgText\').val(); device.optType = \'pausePush\'; var t = JSON.stringify(device); var old = $("#msgcount").html(); $("#msgcount").html(old + "</br>请求报文:<font color=\'blue\'>" + t + "</font>") websocket.send(t); } </script> <body> <input type="text" id="msgText"> <input type="button" onclick="send()" value="发送"> <input type="button" onclick="pause()" value="暂停"> <br> <div id="msgcount"></div> </body> </html>
后端需要三个类:注册类、握手类、处理类(终端类)
握手类:
import java.net.InetSocketAddress; import java.net.URI; import java.util.Map; import javax.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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.HandshakeInterceptor; public class WebSocketHandshakeInterceptor implements HandshakeInterceptor { private static Logger logger = LoggerFactory .getLogger(HandshakeInterceptor.class); @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(true); // 保存session中已登录的用户到websocket的上下文环境中。在推送消息的时候,需要根据当前登录用户获取点位权限 final IbmsUser user = IbmsUserHolder.getUser(); attributes.put(IBMSConstant.SESSION_WEBSOCKET_LOGINED_USER, user); // if (session != null) { // // 使用userName区分WebSocketHandler,以便定向发送消息 // String userName = (String) session // .getAttribute(Constants.SESSION_USERNAME); // if(userName==null){ // userName = "qianshihua"; // } // attributes.put(Constants.WEBSOCKET_USERNAME, userName); // } } return true; } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { URI uri = request.getURI(); InetSocketAddress remoteAddress = request.getRemoteAddress(); String msg = "afterHandshake*******************\\r\\nuri:" + uri + ";\\r\\nremoteAddress;" + remoteAddress; System.err.println(msg); logger.debug(msg); } }
websocket注册类,注册类依赖握手类,可以编码实现,也可以直接通过spring配置实现:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; @Configuration @EnableWebMvc @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(systemWebSocketHandler(),"/point/webSocketServer.do").addInterceptors(new WebSocketHandshakeInterceptor()) // .setAllowedOrigins("http://localhost:8087","http://10.16.38.21:8087","http://localhost:63342") ; registry.addHandler(systemWebSocketHandler(), "/point/sockjs/webSocketServer.do").addInterceptors(new WebSocketHandshakeInterceptor()) .withSockJS(); registry.addHandler(indexConfigWebSocketHandler(),"/app/indexConfig/indexConfigWebSocket.do").addInterceptors(new WebSocketHandshakeInterceptor()); } @Bean public WebSocketHandler systemWebSocketHandler(){ return new IbmsWebSocketHandler(); } @Bean public WebSocketHandler indexConfigWebSocketHandler(){ return new IndexConfigWebSocketHandler(); } }
后端可以注册多个handler,如上图配置。
handler:
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject;import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.WebSocketMessage; import org.springframework.web.socket.WebSocketSession; import java.util.List; /** * 数据订阅处理类 */ public class IndexConfigWebSocketHandler implements WebSocketHandler { private static final Logger logger = LoggerFactory.getLogger(IndexConfigWebSocketHandler.class); @Override public void afterConnectionEstablished(WebSocketSession webSocketSession) throws Exception { logger.debug("indexconfig connect to the websocket success......"); } /** * 处理前端发起的订阅信息 * 订阅列表中的id包含fmt前缀 * * @param session * @param message * @throws Exception */ @Override public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { String jsontext = (String) message.getPayload(); logger.info("收到统计项订阅:::" + jsontext); Object objUser = session.getAttributes().get( IBMSConstant.SESSION_WEBSOCKET_LOGINED_USER); if (objUser == null) { // 取不到session中的用户信息 throw new RuntimeException("会话中无用户信息"); } JSONObject jsonObject = JSONObject.parseObject(jsontext); Object optType = jsonObject.get("optType");//状态字段 String data = jsonObject.getString("data");//数据字段 //将数据字段解析成SubscribeBO列表 List<SubscribeBO> subscribeBOs = JSON.parseArray(data, SubscribeBO.class); boolean ignoreSession = false; if (subscribeBOs == null || subscribeBOs.size() == 0) { if ("pausePush".equals(optType)) { //如果data为空,并且optType==pausePush,关闭该session的所有推送 this.removeReader(session); } WebSocket.之.基础入门-建立连接maven web项目的web.xml报错The markup in the document following the root element must be well-formed.(代码片段