Java EE HTML5 WebSocket 示例

jopen 11年前發布 | 107K 次閱讀 WebSocket WebSocket 開發

在本教程中,我們將借助于Java EE的WebSocket(服務器端)實現一個HTML5的WebSocket連接。

1. 介紹

HTML5給Web瀏覽器帶來了全雙工TCP連接websocket標準服務器的能力。

換句話說,瀏覽器能夠與服務器建立連接,通過已建立的通信信道來發送和接收數據而不需要由HTTP協議引入額外其他的開銷來實現。

在本教程中我們將在Java EE環境下實現一個簡單的websockect服務器端來和客戶端進行數據交互。

本教程需要以下環境:

  1. Ubuntu 12.04
  2. JDK 1.7.0.21
  3. Glassfish 4.0
: Java EE 7中才引入了WebSocket。

2. WebSocket服務器端

讓我們定義一個 Java EE websocket服務器端:

WebSocketTest.java

package com.byteslounge.websockets;

import java.io.IOException;

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

@ServerEndpoint("/websocket")
public class WebSocketTest {

  @OnMessage
  public void onMessage(String message, Session session) 
    throws IOException, InterruptedException {

    // Print the client message for testing purposes
    System.out.println("Received: " + message);

    // Send the first message to the client
    session.getBasicRemote().sendText("This is the first server message");

    // Send 3 messages to the client every 5 seconds
    int sentMessages = 0;
    while(sentMessages < 3){
      Thread.sleep(5000);
      session.getBasicRemote().
        sendText("This is an intermediate server message. Count: " 
          + sentMessages);
      sentMessages++;
    }

    // Send a final message to the client
    session.getBasicRemote().sendText("This is the last server message");
  }

  @OnOpen
  public void onOpen() {
    System.out.println("Client connected");
  }

  @OnClose
  public void onClose() {
    System.out.println("Connection closed");
  }
}
你可能已經注意到我們從 javax.websocket包中引入了一些類。

@ServerEndpoint 注解是一個類層次的注解,它的功能主要是將目前的類定義成一個websocket服務器端。注解的值將被用于監聽用戶連接的終端訪問URL地址。

onOpenonClose 方法分別被@OnOpen@OnClose 所注解。這兩個注解的作用不言自明:他們定義了當一個新用戶連接和斷開的時候所調用的方法。

onMessage 方法被@OnMessage所注解。這個注解定義了當服務器接收到客戶端發送的消息時所調用的方法。注意:這個方法可能包含一個javax.websocket.Session可選參數(在我們的例子里就是session參數)。如果有這個參數,容器將會把當前發送消息客戶端的連接Session注入進去。

本例中我們僅僅是將客戶端消息內容打印出來,然后首先我們將發送一條開始消息,之后間隔5秒向客戶端發送1條測試消息,共發送3次,最后向客戶端發送最后一條結束消息。

3. 客戶端

現在我們要來寫websocket測試應用的客戶端:

page.html

<!DOCTYPE html>
<html>
<head>
<title>Testing websockets</title>
</head>
<body>
  <div>
    <input type="submit" value="Start" onclick="start()" />
  </div>
  <div id="messages"></div>
  <script type="text/javascript">
    var webSocket = 
      new WebSocket('ws://localhost:8080/byteslounge/websocket');

    webSocket.onerror = function(event) {
      onError(event)
    };

    webSocket.onopen = function(event) {
      onOpen(event)
    };

    webSocket.onmessage = function(event) {
      onMessage(event)
    };

    function onMessage(event) {
      document.getElementById('messages').innerHTML 
        += '<br />' + event.data;
    }

    function onOpen(event) {
      document.getElementById('messages').innerHTML 
        = 'Connection established';
    }

    function onError(event) {
      alert(event.data);
    }

    function start() {
      webSocket.send('hello');
      return false;
    }
  </script>
</body>
</html>

這是一個簡單的頁面,包含有JavaScript代碼,這些代碼創建了一個websocket連接到websocket服務器端。

onOpen 我們創建一個連接到服務器的連接時將會調用此方法。

onError 當客戶端-服務器通信發生錯誤時將會調用此方法。

onMessage 當從服務器接收到一個消息時將會調用此方法。在我們的例子中,我們只是將從服務器獲得的消息添加到DOM。

我們連接到websocket 服務器端,使用構造函數 new WebSocket() 而且傳之以端點URL:

ws://localhost:8080/byteslounge/websocket

4. 測試

現在我們可以訪問測試頁面對我們的應用進行測試:

http://localhost:8080/byteslounge/page.html

正如所期望的,我們將看到 Connection established 消息:

http://localhost:8080/byteslounge/page.html

現在只要我們一按按鈕,就會通過此websocket發送初始化報文給服務器,而且接下來會收到發自服務器的測試消息:

服務器發送、客戶端接收的消息

5. WebSockets 握手

客戶端和服務器端TCP連接建立在HTTP協議握手發生之后。通過HTTP流量調試,很容易觀察到握手。客戶端一創建一個 WebSocket實例,就會出現如下請求和服務器端響應:

注意: 我們只錄入了WebSocket握手所用到的HTTP頭。

請求:

GET /byteslounge/websocket HTTP/1.1
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Key: wVlUJ/tu9g6EBZEh51iDvQ==

響應:

HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: websocket
Sec-WebSocket-Accept: 2TNh+0h5gTX019lci6mnvS66PSY=

注意:進行連接需要將通過Upgrade and Upgrade將協議升級到支持websocket HTTP頭的Websocket協議。服務器響應表明請求被接受,協議將轉換到WebSocket協議(HTTP狀態碼101):

HTTP/1.1 101 Web Socket Protocol Handshake

6. 下載源碼

在本頁的末尾有范例源代碼下載鏈接,源碼在Glassfish 4(你需要一個兼容Java EE 7的服務器)上通過測試。
在如下地址下載范例源碼:
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!