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.之.基础入门-建立连接

JAVA WEB代码片段

maven web项目的web.xml报错The markup in the document following the root element must be well-formed.(代码片段

纯 Java 中的 WebSocket

websocket入门例子

Websocket 不工作:意外响应代码 404