• WebSocket


     WebSocket 作为一种浏览器与服务器的核心通信技术,被嵌入到了浏览器的内核中。WebSocket 的出现使得浏览器提供对 Socket 的支持成为可能,从而在浏览器和服务器之间提供了一个基于 TCP 连接的双向通道。以前的服务器消息推送大部分采用的都是“轮询”和“长连接”技术,这两中技术都会对服务器产生相当大的开销,而且实时性不是特别高。WebSocket技术对只会产生很小的开销,并且实时性特别高。

    服务器端(server):

    我是JMS是接收数据源,数据处理后,发送onmessage给客户端

    package com.ship;
    
    import java.io.IOException;
    import java.util.Properties;
    import java.util.Set;
    import java.util.concurrent.CopyOnWriteArraySet;
    import javax.annotation.PostConstruct;
    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.Destination;
    import javax.jms.JMSException;
    import javax.jms.Message;
    import javax.jms.MessageConsumer;
    import javax.jms.MessageListener;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    import javax.websocket.OnClose;
    import javax.websocket.OnError;
    import javax.websocket.OnMessage;
    import javax.websocket.OnOpen;
    import javax.websocket.server.ServerEndpoint;
    import org.apache.activemq.ActiveMQConnectionFactory;
    import org.springframework.stereotype.Controller;
    import com.common.utils.PropertyLoader;
    
    @Controller
    @ServerEndpoint(value = "/ws")
    public class WSserver implements MessageListener {
        private static WSserver instance = null;
        private javax.websocket.Session wssession;
        private static final Set<WSserver> connections = new CopyOnWriteArraySet<WSserver>();
    
        public WSserver() {
            instance = this;
        }
    
        public WSserver getInstance() {
            return instance;
        }
    
        //感知接收数据源
        @Override
        public void onMessage(Message message) {
            if (message instanceof TextMessage) {
                TextMessage txtMsg = (TextMessage) message;
                try {
                    String content = txtMsg.getText();
                    // System.out.println("感知数据是:
    " + content);
                    String[] arrcontent = content.split("
    ");
                    for (int i = 0; i < arrcontent.length; i++) {
                        String[] shipinfo = arrcontent[i].split(",");
                            String shipname=shipinfo[0];
                            String mess=shipname;
                            //服务器发送数据
                            onMessage(mess);
                    }
    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    
        @PostConstruct
        public void init() {
            try {
                buildJmsCon();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public void buildJmsCon() {
            // 消费者的主要流程
            Connection connection = null;
            Properties properties = PropertyLoader.getPropertiesFromClassPath(
                    "activemq.properties", "UTF-8");
            String topic = properties.getProperty("topic");
            String username = properties.getProperty("username");
            String password = properties.getProperty("password");
            String ipaddress = properties.getProperty("ipaddress");
            String port = properties.getProperty("port");
            String brokerURL = "failover://tcp://" + ipaddress + ":" + port;
            try {
                // 1.初始化connection工厂
                ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
                        username, password, brokerURL);
    
                // 2.创建Connection
                connection = connectionFactory.createConnection();
    
                // 3.打开连接
                connection.start();
    
                System.out.println("连接成功..................");
    
                // 4.创建session
                Session session = connection.createSession(false,
                        Session.AUTO_ACKNOWLEDGE);
    
                // 5.创建消息目标
                Destination destination = session.createTopic(topic);
    
                // 6.创建消费者
                MessageConsumer consumer = session.createConsumer(destination);
    
                // 7.配置监听
                consumer.setMessageListener(getInstance());
    
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    
        @OnOpen
        public void onOpen(javax.websocket.Session session) {
            this.wssession = session;
            connections.add(this);
        }
    
        @OnClose
        public void onClose() {
            connections.remove(this);
            String message = "onClose";
            WSserver.broadCast(message);
        }
    
        @OnMessage
        public void onMessage(String message) {
            WSserver.broadCast(message);
        }
    
        @OnError
        public void onError(Throwable throwable) {
            System.out.println(throwable.getMessage());
        }
    
        private static void broadCast(String message) {
            for (WSserver ws : connections) {
                try {
                    synchronized (ws) {
                        ws.wssession.getBasicRemote().sendText(message);
                    }
                } catch (IOException e) {
                    connections.remove(ws);
                    try {
                        ws.wssession.close();
                    } catch (IOException e1) {
                    }
                    WSserver.broadCast("error");
                }
            }
        }
    
    }

    客户端(client):

    package bjs;
    
    import java.net.URI;
    import java.net.URISyntaxException;
    import java.util.Scanner;
    
    import org.java_websocket.client.WebSocketClient;
    import org.java_websocket.drafts.Draft_17;
    import org.java_websocket.handshake.ServerHandshake;
    
    public class WSClient {
    
        public static WebSocketClient initWs() throws URISyntaxException{
            //ws:开头 项目路径+服务器的值 @ServerEndpoint(value = "/ws")
            String url = "ws://192.168.1.252:8080/ganzhi/ws";
            WebSocketClient wc = new WebSocketClient(new URI(url), new Draft_17()) {
    
                @Override
                public void onClose(int arg0, String arg1, boolean arg2) {
                    // TODO Auto-generated method stub
    
                }
    
                @Override
                public void onError(Exception arg0) {
                    // TODO Auto-generated method stub
                       System.out.println("error client");
                }
    
                @Override
                public void onMessage(String arg0) {
                    // TODO Auto-generated method stub
                System.out.println("server message:  "+arg0);
                }
    
                @Override
                public void onOpen(ServerHandshake arg0) {
                    // TODO Auto-generated method stub
                  System.out.println("client open:  "+arg0.getHttpStatusMessage());
                }
    
            };
            wc.connect();
            return wc;
        }
        
        public static void receiveWs(WebSocketClient wc) throws URISyntaxException {
            Scanner scanner = new Scanner(System.in);
            while (true) {
                String message = scanner.nextLine();
                if (message.equals("q")) {
                    System.out.println("if blank");
                    wc.close();
                    continue;
                }else {
                    System.out.println("else blank");
                    wc.send(message);
                }
            
            }
        }
        
        public static void main(String[] args) throws URISyntaxException {
            WebSocketClient wc=initWs();
            receiveWs(wc);        
        }
    }

    客户端测试:

    client open: Switching Protocols
    server message: 浙越城货0585
    server message: 通达148
    server message: 鲁济宁货4588
    server message: 皖华瑞696

    HTML: 

    var webSocket = null;
    var tryTime = 0;
    $(document).ready(function() {
        var token = $("#token").val();
        var map = new BMap.Map("divmap");// 创建地图实例
        map.enableScrollWheelZoom();
        map.centerAndZoom("嘉兴", 12);
        /*
         * map.addControl(new BMap.NavigationControl()); map.addControl(new
         * BMap.ScaleControl());
         */
        if (token == null || token == 'null' || token == '') {
            window.location.href = "/jiaxingport";
        } else {
            loaddata(map);
        }
        $("#searchbtn").click(function() {
            searchship(map);
        });
        /*
         * window.setInterval(function() { loaddata(map); }, 30000);
         */
        initSocket(map);
        window.onbeforeunload = function() {
            // 离开页面时的其他操作
        };
    });
    
    function loaddata(map) {
        map.clearOverlays(); // 清除覆盖物
        $.ajax({
            "url" : "queryshipaisnumpc",
            "data" : {
                'token' : $("#token").val()
            },
            "type" : "post",
            "datatype" : "json",
            "success" : function(resp) {
                var shiplist = resp.baseResult.map.shiplist;
                var starttime = resp.baseResult.map.starttime;
                var endtime = resp.baseResult.map.endtime;
                $("#starttime").val(starttime);
                $("#endtime").val(endtime);
                $("#showtimetxt").val("船舶数据最后有效时间:" + starttime);
                showships(shiplist, map);
            }
        });
    }
    
    function searchship(map) {
        var starttime = $("#starttime").val();
        var content = $("#content").val();
        if (content == null || content == '请输入船名') {
            alert("请输入正确的船名!");
            return false;
        }
        map.clearOverlays(); // 清除覆盖物
        $.ajax({
            "url" : "searchshipbyname",
            "data" : {
                'token' : $("#token").val(),
                'starttime' : starttime,
                'content' : content
            },
            "type" : "post",
            "datatype" : "json",
            "success" : function(resp) {
                var shiplist = resp.baseResult.map.shiplist;
                // 地点标船
                if (shiplist != null && shiplist.length > 0) {
                    $("#showtimetxt").val("船舶数据最后有效时间:" + starttime);
                    showships(shiplist, map);
                } else {
                    alert("未找到相应船舶");
                    window.location.reload();
                }
            }
        });
    }
    
    function showships(shiplist, map) {
        if (shiplist != null && shiplist.length > 0) {
            for (var i = 0; i < shiplist.length; i++) {
                drawMarker(shiplist[i], map);
            }
        }
    }
    
    function drawMarker(shipinfo, map) {
        var html = "船名:<label>" + shipinfo.shipname + "</label><br>ais:<label>"
                + shipinfo.ais + "</label><br>最后航行时间:<label>"
                + shipinfo.shipdate.substr(11, 16)
                + "</label><br><a style='color:red' onclick='showshipdetail(""
                + shipinfo.shipname + "")'>船舶详情</a>";
        var point = new BMap.Point(shipinfo.longitude, shipinfo.latitude);// 创建点坐标
        var label = new BMap.Label(shipinfo.shipname, {
            offset : new BMap.Size(20, -10)
        });
        var myIcon = null
        if (shipinfo.shiptype == 1) {
            myIcon = new BMap.Icon("/jiaxingport/image/main/ds.png", new BMap.Size(
                    20, 20));
        } else {
            myIcon = new BMap.Icon("/jiaxingport/image/main/uds.png",
                    new BMap.Size(20, 20));
        }
        var marker = new BMap.Marker(point, {
            icon : myIcon
        }); // 创建标注
        label.setStyle({
            display : "none" // 给label设置样式,任意的CSS都是可以的
        });
        marker.setLabel(label);
        map.addOverlay(marker); // 将标注添加到地图中
        var infoWindow = new BMap.InfoWindow(html);
        marker.infoWindow = infoWindow;// 多点添加文字信息
        marker.addEventListener("click", function(e) {
            this.openInfoWindow(e.target.infoWindow);
        });
    }
    
    function showshipdetail(shipname) {
        window.location.href = "/jiaxingport/page/ais/shipinfo.jsp?name="
                + shipname;
    }
    
    /**
     * 初始化websocket,建立连接
     */
    function initSocket(map) {
        if (!window.WebSocket) {
            alert("您的浏览器不支持websocket!");
            return false;
        }
        //项目名+ServerEndpoint名
        webSocket = new WebSocket("ws://localhost:8080/ganzhi/ws");
        // 收到服务端消息
        webSocket.onmessage = function(msg) {
            var mess = msg.data;
            var arr = {};
            arr = mess.split(",");
            var shipname = arr[0];
    
            var shipinfo = {
                "shipname" : shipname,
                "longitude" : arr[1],
                "latitude" : arr[2],
                "ais" : arr[3],
                "shipdate" : arr[4],
                "shiptype" : arr[5]
            };
            var allOverlay = map.getOverlays();
            for (var i = 0; i < allOverlay.length - 1; i++) {
                if (allOverlay[i].toString() == "[object Marker]"
                        && allOverlay[i].getLabel().content == shipname) {
                    //移除marker
                    map.removeOverlay(allOverlay[i]);
                    break;
                }
            }
            //画marker
            drawMarker(shipinfo, map);
        };
    
        // 异常
        webSocket.onerror = function(event) {
            console.log(event);
        };
    
        // 建立连接
        webSocket.onopen = function(event) {
            console.log(event);
        };
    
        // 断线重连
        webSocket.onclose = function() {
            // 重试10次,每次之间间隔10秒
            if (tryTime < 10) {
                setTimeout(function() {
                    webSocket = null;
                    tryTime++;
                    initSocket();
                }, 500);
            } else {
                tryTime = 0;
            }
        };
    
    }
  • 相关阅读:
    [国嵌笔记][001-003][嵌入式系统概述]
    世界第一魔法师
    详解CSS display:inline-block的应用(转)
    详解CSS float属性(转)
    CSS代码重构与优化之路(转)
    未能加载文件或程序集“XXX”或它的某一个依赖项。试图加载格式不正确的程序。(转)
    【总结整理】display与position之间的关系【较完整】(转)
    css知多少(11)——position(转)
    【总结整理】行内标签span设置position:absolute/float属性可以设置宽度与高度
    【总结整理】display、visibility、overflow的隐藏问题
  • 原文地址:https://www.cnblogs.com/manusas/p/5552171.html
Copyright © 2020-2023  润新知