WebSoket 全双工通信的应用协议理解和实例

来源:互联网 发布:淘宝管控记录是干吗的 编辑:程序博客网 时间:2024/06/06 08:47

WebSocket是一种通过TCP协议提供两个对等体之间的全双通信的应用协议。传统的HTTP请求是不对等的。客户端发送请求是主动地,服务器一直被动(单向通讯),所以WebSoket通过客户端和服务器之间提供全双通道来解决这种限制。WebSocket(一个TCP通讯)包括握手和数据传输两个部分,客户端通过使用URI向WebSocket发送请求握手(一般网络上的数据:UTF-8和二进制文件(二进制最多))。


下面写一个例子实现简单的客户端和服务端之间的响应:

第一步:

首先我们创建一个Java类(EchoEndpoin.java)并实继承Endpoint,实现此类中onOpen方法代码如下:

@Overridepublic void onOpen(Session session, EndpointConfig config) {// TODO Auto-generated method stubsession.addMessageHandler(new MessageHandler.Whole<String>() {@Overridepublic void onMessage(String msg) {// TODO Auto-generated method stubtry {session.getBasicRemote().sendText(msg);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}});}


第二步:

创建一个SocketConfig.java 实现ServerApplicationConfig接口,在getEndpointConfigs方法中实现(其中scanned为此方法参数变量名):

Set<ServerEndpointConfig> result = new HashSet<>();if(scanned.contains(EchoEndpoin.class)) { result.add(ServerEndpointConfig.Builder.create(EchoEndpoin.class, "/echo").build()); }return result;

注意:上面“/echo” 和你Echoendpoin.class中的注记名一样


第三步:

新建一个echo.xhtml文件,下面贴出此页面的代码:
<?xml version="1.0" encoding="UTF-8"?><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head>    <title>Apache Tomcat WebSocket Examples: Echo</title>    <style type="text/css"><![CDATA[        #connect-container {            float: left;            width: 400px        }        #connect-container div {            padding: 5px;        }        #console-container {            float: left;            margin-left: 15px;            width: 400px;        }        #console {            border: 1px solid #CCCCCC;            border-right-color: #999999;            border-bottom-color: #999999;            height: 170px;            overflow-y: scroll;            padding: 5px;            width: 100%;        }        #console p {            padding: 0;            margin: 0;        }    ]]></style>    <script type="application/javascript"><![CDATA[        "use strict";        var ws = null;        function setConnected(connected) {            document.getElementById('connect').disabled = connected;            document.getElementById('disconnect').disabled = !connected;            document.getElementById('echo').disabled = !connected;        }        function connect() {            var target = document.getElementById('target').value;            if (target == '') {                alert('Please select server side connection implementation.');                return;            }            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;            }            ws.onopen = function () {                setConnected(true);                log('Info: WebSocket connection opened.');            };            ws.onmessage = function (event) {                log('Received: ' + event.data);            };            ws.onclose = function (event) {                setConnected(false);                log('Info: WebSocket connection closed, Code: ' + event.code + (event.reason == "" ? "" : ", Reason: " + event.reason));            };        }        function disconnect() {            if (ws != null) {                ws.close();                ws = null;            }            setConnected(false);        }        function echo() {            if (ws != null) {                var message = document.getElementById('message').value;                log('Sent: ' + message);                ws.send(message);            } else {                alert('WebSocket connection not established, please connect.');            }        }        function updateTarget(target) {            if (window.location.protocol == 'http:') {                document.getElementById('target').value = 'ws://' + window.location.host + target;            } else {                document.getElementById('target').value = 'wss://' + window.location.host + target;            }        }        function log(message) {            var console = document.getElementById('console');            var p = document.createElement('p');            p.style.wordWrap = 'break-word';            p.appendChild(document.createTextNode(message));            console.appendChild(p);            while (console.childNodes.length > 25) {                console.removeChild(console.firstChild);            }            console.scrollTop = console.scrollHeight;        }        document.addEventListener("DOMContentLoaded", function() {            // Remove elements with "noscript" class - <noscript> is not allowed in XHTML            var noscripts = document.getElementsByClassName("noscript");            for (var i = 0; i < noscripts.length; i++) {                noscripts[i].parentNode.removeChild(noscripts[i]);            }        }, false);    ]]></script></head><body><div class="noscript"><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websockets rely on Javascript being enabled. Please enable    Javascript and reload this page!</h2></div><div>    <div id="connect-container">        <div>            <span>Connect to service implemented using:</span>            <br/>            <!-- echo example using new programmatic API on the server side -->            <input id="radio1" type="radio" name="group1" value="/socket/echo"                   onclick="updateTarget(this.value);"/> <label for="radio1">programmatic API</label>            <br/>            <!-- echo example using new annotation API on the server side -->            <input id="radio2" type="radio" name="group1" value="/socket/delecho"                   onclick="updateTarget(this.value);"/> <label for="radio2">annotation API (basic)</label>            <br/>            <!-- echo example using new annotation API on the server side -->            <input id="radio3" type="radio" name="group1" value="/socket/echo3"                   onclick="updateTarget(this.value);"/> <label for="radio3">annotation API (stream)</label>            <br/>            <!-- echo example using new annotation API on the server side -->            <!-- Disabled by default -->            <!--            <input id="radio4" type="radio" name="group1" value="/examples/websocket/echoAsyncAnnotation"                   onclick="updateTarget(this.value);"/> <label for="radio4">annotation API (async)</label>            -->        </div>        <div>            <input id="target" type="text" size="40" style="width: 350px"/>        </div>        <div>            <button id="connect" onclick="connect();">Connect</button>            <button id="disconnect" disabled="disabled" onclick="disconnect();">Disconnect</button>        </div>        <div>            <textarea id="message" style="width: 350px">Here is a message!</textarea>        </div>        <div>            <button id="echo" onclick="echo();" disabled="disabled" >Echo message</button>         </div>    </div>    <div id="console-container">        <div id="console"/>    </div></div></body></html>

注意这块代码:

            <input id="radio1" type="radio" name="group1" value="/socket/echo"                   onclick="updateTarget(this.value);"/> <label for="radio1">programmatic API</label>

其中value中socket填写你的项目名,echo表示你EchoEndpoin.class中的注记名


最后一步:

发布并访问项目:


选中单选框的第一个,点击Connect,最后点击Echo message发送。效果如右边。


好了。先介绍到这里。欢迎来一起评论交流。哈哈哈