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;
        }
    };

}
原文地址:https://www.cnblogs.com/manusas/p/5552171.html