Java EE HTML5 WebSocket 示例(demo)

在本教程中,我們將藉助於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地址。

onOpen 和 onClose 方法分別被@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" οnclick="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的服務器)上通過測試。
在如下地址下載範例源碼:


來源


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章