基于tomcat運行HTML5 WebSocket echo例子

jopen 9年前發布 | 37K 次閱讀 WebSocket WebSocket 開發

一:概述

作為HTML5新特性之一的WebSocket組件,在實時性有一定要求的WEB應用開發中還是有一定用武之地,高版本的IE、Chrome、FF瀏覽器都支持Websocket,標準的Websocket通信是基于RFC6455實現服務器端與客戶端握手與消息接發的。如果對Websocket通信不是太理解,可以查看RFC文檔即可,簡單說就是通過發送HTTP請求,實現雙方握手,將無狀態的HTTP通信協議進一步升級成有狀態的通信協議,同時Websocket還支持子協議選項與安全傳輸。標準的websocket連接URL以ws開頭,如果是基于TLS的則以wss開頭。基于Websocket可以很方便的開發基于web聊天程序,各種網頁消息通知與推送通知。

         如果非要扒一扒websocket的今生前世的話,還記得最早的基于HTTP輪詢實現網頁即時通信的方式,那種做法比較消耗資源、于是有人改進了編程CometD長連接方式,可是本質上還是換湯不換藥,而websocket的出現正好解決了這些問題,但是很多瀏覽器的低版本還是不支持websocket,于是還催生了一些基于websocket理念實現的JS通信框架,其中學得比較像的有SockJS與socket.io,他們都號稱支持websocket,然后如果瀏覽器端不支持原生的websocket,它們會自動啟用fallback選項使用其它諸如ajax、Http輪詢、長輪詢/連接、甚至是flash的socket等機制實現模擬websocket的工作方式,但是他們最大的弊端是如果客戶端使用了這些框架,服務器必須用它們,否則等待開發者就是一大堆無法回避的問題,同時很多都是無解的。主要原因在于它們實現自己的協議集,不照它們的格式處理數據沒法玩。閑話說的有點多。

二 : 實現步驟

Tomcat7的高版本中實現了websocket服務器端RFC6455標準協議,可以跟瀏覽器端websocket進行通信,首先要做好如下幾步:


1.      安裝高版本JDK – JDK8

2.      安裝tomcat 7.0.64

3.      在eclipse中建立一個動態的web項目

 

根據JSR標準,Java中實現websocket的標準接口可以基于注解方式,tomcat也搞好了,只有我們實現如下代碼,即可創建一個websocket回聲服務器:

 

package com.websocket.demo;

import java.io.IOException; import java.nio.ByteBuffer;

import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value = "/echo") public class EchoExample {

@OnMessage
public void echoTextMessage(Session session, String msg, boolean last) {
    try {
        if (session.isOpen()) {
            System.out.println("received from client message = " + msg);
            session.getBasicRemote().sendText(msg, last);
        }
    } catch (IOException e) {
        try {
            session.close();
        } catch (IOException e1) {
        }
    }
}

@OnOpen
public void openConn(Session session) throws IOException {
    session.getBasicRemote().sendText("hello web socket"); // means open it
}

@OnMessage
public void echoBinaryMessage(Session session, ByteBuffer bb, boolean last) {
    System.out.println("send binary message...");
    try {
        if (session.isOpen()) {
            System.out.println("byte buffer lenghth : " + bb.array().length);
            System.out.println("byte buffer content: " + ((bb.array()[0]) & 0xff));
            System.out.println("byte buffer content: " + ((bb.array()[1]) & 0xff));
            System.out.println("byte buffer content: " + ((bb.array()[2]) & 0xff));
            session.getBasicRemote().sendBinary(bb, last);
        }
    } catch (IOException e) {
        try {
            session.close();
        } catch (IOException e1) {
            // Ignore
        }
    }
}

}</pre>


如何在tomcat中啟動websocket服務器,首先需要在web.xml添加如下配置:


  <listener>
        <listener-class>org.apache.tomcat.websocket.server.WsContextListener</listener-class>
    </listener>

然后實現ServerApplicationConfig接口,實現如下:



/
 
 */
package com.config.websocket.client;

import java.util.HashSet; import java.util.Set;

import javax.websocket.Endpoint; import javax.websocket.server.ServerApplicationConfig; import javax.websocket.server.ServerEndpointConfig;

public class ScanWebSocketSeverConfig implements ServerApplicationConfig {

@Override
public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> scanned) {

    Set<ServerEndpointConfig> result = new HashSet<ServerEndpointConfig>();

/ if (scanned.contains(EchoWsChatSever.class)) { result.add(ServerEndpointConfig.Builder.create(EchoWsChatSever.class, "/echo").build()); }/ return result; }

@Override
public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
    Set<Class<?>> results = new HashSet<Class<?>>();
    for (Class<?> clazz : scanned) {
        if (clazz.getPackage().getName().startsWith("com.websocket.")) {
            System.out.println("find end point : " + clazz.getName());
            results.add(clazz);
        }
    }
    return results;
}

}</pre>
創建網頁echo.html,內容如下:



<html>
<head>
<title>Web Socket Echo Test</title>
<script>
        var ws = null;
        var count = 0;
        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);
            if(event.data instanceof ArrayBuffer)
            {
                var bytes = new Uint8Array(event.data);
                alert(bytes.length + " : " + bytes[0]);
            }
        };
        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.doClose();
            ws = null;
        }
        setConnected(false);
    }

    function echo() {
        if (ws != null) {
            var message = document.getElementById('message').value;
            log('Sent: ' + message);
            ws.send(JSON.stringify({'textMessage': message})); 
            count++
        } else {
            alert('WebSocket connection not established, please connect.');
        }
    }

    function log(message) {
        var echomsg = document.getElementById('echomsg');
        var p = document.createElement('p');
        p.style.wordWrap = 'break-word';
        p.appendChild(document.createTextNode(message));
        echomsg.appendChild(p);
        while (echomsg.childNodes.length > 25) {
            echomsg.removeChild(console.firstChild);
        }
        echomsg.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> <h4>URL - ws://localhost:8080/websocket/echo</h4> <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 id="echomsg"> </div> </body> </html></pre>三 :運行與測試


打包部署到tomcat之后,啟動chrom瀏覽器,輸入地址:

http://localhost:8080/websocket/echo.html 

后來,我還發現,tomcat實現websocket服務器端居然不支持子協議

跟3W上的測試URL結果不一樣。

來自:http://blog.csdn.net/jia20003/article/details/48751847

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!