学习WebSocket(二)

webSocket配置类

import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;
import java.util.Set;

/**
 * @author baozi
 * @title webSocket服务配置类
 * @date 2018/4/14 10:45
 * @description
 */
public class WebSocketConfig implements ServerApplicationConfig {
    /*
     * 1.  getAnnotatedEndpointClasses
     * 2.  getEndpointConfigs
     *
     * 上面的两个方法都是用来注册 webSocket的。   只不过注册的方式不同。  1方法是 注解的方式
     * 2方法是 接口的方式
     *
     * 显然 注解的方式更加的 灵活简单。  接口的方式更加的传统,严谨。
     *
     * (non-Javadoc)
     * @see javax.websocket.server.ServerApplicationConfig#getAnnotatedEndpointClasses(java.util.Set)
     */

    public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> arg0) {
        // argo.size();是去扫描注解@ServerEndpoint的类的个数
        System.out.println("正在扫描所有的webSocket服务!!!" + arg0.size());
        return arg0;
    }

    public Set<ServerEndpointConfig> getEndpointConfigs(
            Set<Class<? extends Endpoint>> arg0) {
        // TODO Auto-generated method stub
        return null;
    }
}

 

首先定义一个WebSocket服务器

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

/**
 * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
 * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
* session.getQueryString()拿到的是,页面连接服务器时的?后面的值 (ip=xxx.xxx.xxx.xxx)
* var target = "ws://localhost:8080/websocket?ip=" + ip;
*/ @ServerEndpoint("/websocket") public class MyWebSocket { /** * 与某个客户端的连接会话,需要通过它来给客户端发送数据 */ private Session session; /** * 连接建立成功调用的方法 * Session是webSocket的回话,一个session 代表一个通信会话 * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据 */ @OnOpen public void onOpen(Session session) { this.session = session; System.out.println("sessionID:" + session.getId()); WebSocketMapUtil.put(session.getQueryString().split("=")[1],session); } /** 连接关闭调用的方法 */ @OnClose public void onClose() { //从map中删除 WebSocketMapUtil.remove(session.getQueryString().split("=")[1]); System.out.println("连接关闭"); } /** * 发生错误时调用 * @param session * @param error */ @OnError public void onError(Session session, Throwable error){ error.printStackTrace(); } /** * 发送消息方法。 * @param message * @throws IOException */ public void sendMessage(String ip,String message) throws IOException{ String trim = ip.trim(); if(trim != null && WebSocketMapUtil.getValues() != null){ WebSocketMapUtil.get(trim).getBasicRemote().sendText(message); } } }

服务器的工具类

import javax.websocket.Session;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * @author baozi
 * @title  
 * @date 2018/4/14 9:01
 * @description
 */
public class WebSocketMapUtil {

    public static ConcurrentMap<String, Session> webSocketMap = new ConcurrentHashMap<>();

    public static void put(String key, Session session){
        webSocketMap.put(key, session);
    }

    public static Session get(String key){
        return webSocketMap.get(key.trim());
    }

    public static void remove(String key){
        webSocketMap.remove(key);
    }

    public static Collection<Session> getValues(){
        return webSocketMap.values();
    }
}

服务端发送客户端

 /**
   * webSocket发送消息给客户端 start
   */
    MyWebSocket myWebSocket = new MyWebSocket();
    ClassFlow classFlow = new ClassFlow();
    classFlow.setIntNum(22);
    classFlow.setOutNum(12);
    try {
           classFlow.setPeople(people);
           myWebSocket.sendMessage(ip,new Gson().toJson(classFlow));
    /**
    * webSocket发送消息给客户端 end
      */

页面的逻辑

<%@ page language="java" import="java.util.*" pageEncoding="Utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!doctype html>
<%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html lang="en">
<head>
    <title></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Pragma" content="no-cache" />
    <meta http-equiv="Cache-Control" content="no-cache, must-revalidate" />
    <meta http-equiv="Expires" content="0" />
    <script>
        document.write("<link type='text/css' href='<%=basePath %>module/css/video/demo.css?version=" + new Date().getTime() + "' rel='stylesheet' />");
    </script>
    <link href="<%=basePath %>media/assets/css/bootstrap.css" rel="stylesheet">
</head>
<style>
    .wrapper {
        margin-top:70px !important;
    }
</style>

<body>
    <section class="wrapper">
        <div class="row mt" id="classDiv">
            <c:forEach items="${classrooms}" var="c">
                <div class="col-md-2" style="cursor:pointer;height: 100px;background: gray;text-align: center;padding-top: 30px;margin: 10px;" onclick="ws_init('${c.ips}')">
                    <div>${c.name}</div>
                    <div>${c.num}</div>
                </div>
            </c:forEach>
        </div>

        <div class="left" >
            <div id="videoLeft" style="display: none">
                <div id="divPlugin" class="plugin"></div>
                <input type="button" class="btn" value="开始预览" onclick="clickStartRealPlay();" />
            </div>
                <fieldset class="login" style="display: none">
                <legend>登录</legend>
                <table cellpadding="0" cellspacing="3" border="0">
                    <tr>
                        <td class="tt">IP地址</td>
                        <td><input id="loginip" type="text" class="txt" value="192.168.5.16" /></td>
                        <td class="tt">端口号</td>
                        <td><input id="port" type="text" class="txt" value="80" /></td>
                    </tr>
                    <tr>
                        <td class="tt">用户名</td>
                        <td><input id="username" type="text" class="txt" value="admin" /></td>
                        <td class="tt">密码</td>
                        <td><input id="password" type="password" class="txt" value="hk123456" /></td>
                    </tr>
                    <tr>
                        <td class="tt">设备端口</td>
                        <td colspan="2"><input id="deviceport" type="text" class="txt" value="8000" />(可选参数)</td>
                        <td>
                            窗口分割数&nbsp;
                            <select class="sel2" onchange="changeWndNum(this.value);">
                                <option value="1" selected>1x1</option>
                                <option value="2">2x2</option>
                                <option value="3">3x3</option>
                                <option value="4">4x4</option>
                            </select>
                        </td>
                    </tr>
                    <tr>
                        <td colspan="4">
                            <input type="button" class="btn" id="loginBtn" value="登录" onclick="clickLogin();" />
                            <input type="button" class="btn" value="退出" onclick="clickLogout();" />
                            <input type="button" class="btn2" value="获取基本信息" onclick="clickGetDeviceInfo();" />
                        </td>
                    </tr>
                    <tr>
                        <td class="tt">已登录设备</td>
                        <td>
                            <select id="ip" class="sel" onchange="getChannelInfo();"></select>
                        </td>
                        <td class="tt">通道列表</td>
                        <td>
                            <select id="channels" class="sel"></select>
                        </td>
                    </tr>
                </table>
            </fieldset>
        </div>
        <div class="left">
            <fieldset class="preview" style="display: none">
                <legend>预览</legend>
                <table cellpadding="0" cellspacing="3" border="0">
                    <tr>
                        <td class="tt">码流类型</td>
                        <td>
                            <select id="streamtype" class="sel">
                                <option value="1">主码流</option>
                                <option value="2">子码流</option>
                                <option value="3">第三码流</option>
                                <option value="4">转码码流</option>
                            </select>
                        </td>
                        <td>
                            <input type="button" class="btn" value="开始预览" id="realPlayBtn" onclick="clickStartRealPlay();" />
                            <input type="button" class="btn" value="停止预览" onclick="clickStopRealPlay();" />
                        </td>
                    </tr>
                    <tr>
                        <td class="tt">音量</td>
                        <td>
                            <input type="text" id="volume" class="txt" value="50" maxlength="3" />&nbsp;<input type="button" class="btn" value="设置" onclick="clickSetVolume();" />(范围:0~100)
                        </td>
                        <td>
                            <input type="button" class="btn" value="打开声音" onclick="clickOpenSound();" />
                            <input type="button" class="btn" value="关闭声音" onclick="clickCloseSound();" />
                        </td>
                    </tr>
                    <tr>
                        <td class="tt">对讲通道</td>
                        <td>
                            <select id="audiochannels" class="sel">

                            </select>
                            <input type="button" class="btn" value="获取通道" onclick="clickGetAudioInfo();" />
                        </td>
                        <td>
                            <input type="button" class="btn" value="开始对讲" onclick="clickStartVoiceTalk();" />
                            <input type="button" class="btn" value="停止对讲" onclick="clickStopVoiceTalk();" />
                        </td>
                    </tr>
                    <tr>
                        <td colspan="3">
                            <input type="button" class="btn" value="抓图" onclick="clickCapturePic();" />
                            <input type="button" class="btn" value="开始录像" onclick="clickStartRecord();" />
                            <input type="button" class="btn" value="停止录像" onclick="clickStopRecord();" />
                        </td>
                    </tr>
                    <tr>
                        <td colspan="3">
                            <input type="button" class="btn2" value="启用电子放大" onclick="clickEnableEZoom();" />
                            <input type="button" class="btn2" value="禁用电子放大" onclick="clickDisableEZoom();" />
                            <input type="button" class="btn2" value="启用3D放大" onclick="clickEnable3DZoom();" />
                            <input type="button" class="btn2" value="禁用3D放大" onclick="clickDisable3DZoom();" />
                            <input type="button" class="btn" value="全屏" onclick="clickFullScreen();" />
                        </td>
                    </tr>
                </table>
            </fieldset>
        </div>
        <div class="left" id="videoInfo" style="display:none;margin-left:50px">
            <div>进入人数:<span id="intNum"></span></div>
            <div>离开人数:<span id="outNum"></span></div>
            <div>当前人数:<span id="people"></span></div>
        </div>
    </section>

</body>
<script src="<%=basePath %>module/js/jquery-1.7.1.min.js"></script>
<script src="<%=basePath %>module/js/video/webVideoCtrl.js"></script>
<script src="<%=basePath %>module/js/video/demo.js"></script>
<script type="text/javascript">
 var ws;//一个ws对象就是一个通信管道
    /**
     * 点击班级触发 视频显示
     * @param ip
     */
    function  ws_init(ip) {
        //视频的界面
        $("#videoLeft").show();
        var target = "ws://localhost:8080/websocket?ip=" + ip;
        //浏览器兼容性的判断
        if ('WebSocket' in window) {
            ws = new WebSocket(target);
        } else if ('MozWebSocket' in window) {
            ws = new MozWebSocket(target);
        } else {
            alert('WebSocket is not supported by this browser.');
            return;
        }
        //信息展示
        $("#videoInfo").show();
        //触发设备的登录
        $("#loginBtn").click();
        getChannelInfo();
//        window.setTimeout(document.getElementById("loginBtn").click(), 1000);
        //窗口默认1个
        changeWndNum(1);
        //触发视频预览
//        $("#realPlayBtn").click();
//        window.setTimeout(clickStartRealPlay(), 1000);
        clickStartRealPlay();
//        window.setTimeout($("#realPlayBtn").click(), 1000);

        //页面值的回显
        ws.onmessage = function (evt) {
            var jsonObj = eval('(' + evt.data + ')');
            console.log(jsonObj);
            $("#intNum").text(jsonObj.intNum);
            $("#outNum").text(jsonObj.outNum);

        };
    }

</script>
</html>

 

posted @ 2018-04-16 17:57  夏末、初秋  阅读(321)  评论(0编辑  收藏  举报