JavaEE7 HTML5利用WebSocket實現即時通訊


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

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

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

本教程需要以下環境:

  1. JDK 1.7.0.21
  2. tomcat 7
: Java EE 7中才引入了WebSocket。

WebSocket服務器端

WebSocketServer 代碼:
package com.bing.biz.websocket;

import java.io.IOException;

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

 
//該注解用來指定一個URI,客戶端可以通過這個URI來連接到WebSocket。類似Servlet的注解mapping。無需在web.xml中配置。
@ServerEndpoint("/webSocketServer/{userId}")
public class WebSocketServer {
     
    /**
     * 連接建立成功調用的方法
     * @param session  可選的參數。session為與某個客戶端的連接會話,需要通過它來給客戶端發送數據
     * @throws IOException 
     */
    @OnOpen
    public void onOpen(@PathParam("userId") String userId,Session session) throws IOException{
       /* if(userId!=null){            
            if(!SocketUtils.hasConnection(userId)){
                SocketUtils.put(userId,session);
            }
            else{
                //相同用戶只允許在一個地方登錄(網頁版內部判斷)。
                SocketUtils.sendMessage(userId,"forcelogout","該用戶已在其他地方登錄,此次登錄將被強制退出。",0,"");  
                SocketUtils.remove(userId,session.getId());
                SocketUtils.put(userId,session);
            }
        }*/
        System.out.println("Client connected  "+userId);
    }
     
    /**
     * 連接關閉調用的方法
     */
    @OnClose
    public void onClose(@PathParam("userId") String userId,Session session)throws IOException{
        //SocketUtils.remove(userId,session.getId());
        System.out.println("Connection closed");
    }
     
    /**
     * 收到客戶端消息后調用的方法
     * @param message 客戶端發送過來的消息
     * @param session 可選的參數
     * @throws IOException 
     */
    @OnMessage
    public void onMessage(@PathParam("userId") String userId,String message, Session session) throws IOException {
        // 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){
          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");
    }
     
    /**
     * 發生錯誤時調用
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error){
        error.printStackTrace();
    }
}

你可能已經注意到我們從 javax.websocket包中引入了一些類。

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

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

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

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

 

WebSocket客戶端

index.jsp代碼:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!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">
    //建立websocket連接
     var websocket = new WebSocket('ws://localhost:8080/bing/webSocketServer/bing');
       
       websocket.onopen = function (evnt) {
           document.getElementById('messages').innerHTML
           = 'Connection established';
       };
       websocket.onmessage = function (evnt) {
           document.getElementById('messages').innerHTML
           += '<br />' + event.data;
       };
       websocket.onerror = function (evnt) {
       };
       websocket.onclose = function (evnt) {
       };
 
    function start() {
      websocket.send('hello');
      return false;
    }
  </script>
</body>
</html>

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

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

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

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

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

ws://localhost:8080/bing/webSocketServer/bing  ---bing 后台的userid

 

測試

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

http://localhost:8080/bing/index.jsp

后台:

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM