關於WebSocket技術淺析

WebSocket技術,是用於服務端與瀏覽器端的基於TCP/IP的會話協議所興起的一項技術 但凡TCP/IP協議都會經過三次握手,而後進行會話數據的傳輸。保證數據的可靠性(在網絡技術發達的今天,這點已經再也不是問題了) 此項技術放棄了之前的須要定時給服務器發送請求。由服務器刷新數據,而後返回給客戶端,這樣大大的減小了服務器的負擔 咱們如何去實現WebSocketjavascript

我用的環境爲 jdk1.7+ Tomcat 7.0.52 服務引用的主要Jar包爲 catalina.jar,websocket-api.jar 全來自tomcat/lib下 服務端代碼以下:html

package com.zx.websocket;

import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
/**
 * @ServerEndpoint 註解是一個類層次的註解,它的功能主要是將目前的類定義成一個websocket服務器端,
 * 註解的值將被用於監聽用戶鏈接的終端訪問URL地址,客戶端能夠經過這個URL來鏈接到WebSocket服務器端
 */
@ServerEndpoint(value="/singlewebsocket")
public class WebSocketSingleTest {
	//靜態變量,用來記錄當前在線鏈接數。應該把它設計成線程安全的。
    private static Integer onlineCount = 0;
    //concurrent包的線程安全Map,能夠使用Map來存放,其中Key能夠爲用戶標識
    private static Map<Session, WebSocketSingleTest> map=new ConcurrentHashMap<Session, WebSocketSingleTest>();
	//聲明這是用戶打開鏈接處理的方法
    @OnOpen
	public void OnOpen(Session session) throws IOException
	{
		System.out.println("有新用戶連入!session info is :"+session.getId());
		synchronized (onlineCount) {
			addOnlineCount();//在線用戶加1 此方法同步
		}
		map.put(session, this);//添加用戶信息
		Collection key=map.keySet();
		Iterator it=key.iterator();
		String ids="";
		while(it.hasNext()){
			ids+=((Session)it.next()).getId()+",";
		}
		session.getBasicRemote().sendText(ids);
	}
    //聲明這是用戶關閉鏈接處理的方法
	@OnClose
	public void OnClose(Session session)
	{
		System.out.println("有用戶退出!用戶ID is :"+session.getId());
		synchronized (onlineCount) {
			reduiceOnlineCount();//在線用戶減1 此方法同步
		}
		map.remove(session);//移除用戶信息
	}
	//聲明這是異常處理的方法
	@OnError
    public void onError(Session session, Throwable error){
        System.out.println("發生錯誤");
        error.printStackTrace();
    }
	//聲明這是用戶發送消息的方法
	@OnMessage
	public void OnMessage(String message,Session session)
	{
		System.out.println("來自客戶端的消息:["+message+"]");
		/**
		 * 獲取消息後,讀取message獲取傳輸消息的目標人,根據session的Id能夠遍歷Map集合  獲取Map的對應的Socket類
		 * 而後在由這個Socket類 發送消息 參見sendMessage
		 * 注:目標人消息應該經過Message從前臺傳遞過來,再由後臺遍歷處理
		 */
	}
	public void sendMessage(Session session,String message) throws IOException
	{
		session.getBasicRemote().sendText(message);
	}
	public static int getOnlineCount() {
		return onlineCount;
	}
	public static void setOnlineCount(int onlineCount) {
		WebSocketSingleTest.onlineCount = onlineCount;
	}
	public synchronized void addOnlineCount()
	{
		WebSocketSingleTest.onlineCount++;
		
	}
	public synchronized void reduiceOnlineCount()
	{
		WebSocketSingleTest.onlineCount--;
		
	}
}

Jsp端主要JS代碼以下:java

<%@ page language="java" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
    <title>Java後端WebSocket的Tomcat實現</title>
</head>
<body>
    Welcome<br/><input id="text" type="text"/>
    <button onclick="send()">發送消息</button>
    <hr/>
    <button onclick="closeWebSocket()">關閉WebSocket鏈接</button>
    <hr/>
    <div id="message"></div>
</body>

<script type="text/javascript">
    var websocket = null;
    //判斷當前瀏覽器是否支持WebSocket
    if ('WebSocket' in window) {
        websocket = new WebSocket("ws://localhost:8080/websocket/zxwebsocket");
    }
    else {
        alert('當前瀏覽器 Not support websocket')
    }

    //鏈接發生錯誤的回調方法
    websocket.onerror = function () {
        setMessageInnerHTML("WebSocket鏈接發生錯誤");
    };

    //鏈接成功創建的回調方法
    websocket.onopen = function () {
        setMessageInnerHTML("WebSocket鏈接成功");
    }

    //接收到消息的回調方法
    websocket.onmessage = function (event) {
        setMessageInnerHTML(event.data);
    }

    //鏈接關閉的回調方法
    websocket.onclose = function () {
        setMessageInnerHTML("WebSocket鏈接關閉");
    }

    //監聽窗口關閉事件,當窗口關閉時,主動去關閉websocket鏈接,防止鏈接還沒斷開就關閉窗口,server端會拋異常。
    window.onbeforeunload = function () {
        closeWebSocket();
    }

    //將消息顯示在網頁上
    function setMessageInnerHTML(innerHTML) {
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //關閉WebSocket鏈接
    function closeWebSocket() {
        websocket.close();
    }

    //發送消息
    function send() {
        var message = document.getElementById('text').value;
        websocket.send(message);
    }
</script>
</html>

這樣一個消息推送機制就完成了web

其中發佈的時候我碰到的一些問題,在第一次訪問的時候, 服務器後臺會抱一個錯,這個錯是一個類型轉換異常, DefaultInstanceManager cannot be cast to InstanceManager 百度後知道, 在發佈的時候tomcat會將 catalina.jar包加到項目的web-inf下面的lib文件夾下面,這樣這個包就會和tomcat下面的lib下面的catalina.jar 包衝突會報java.lang.ClassCastException 解決方案一:在部署的時候 須要在發佈後的項目WEB-INF/lib下去掉catalina.jar和websocket-api.jar 解決方案二:修改了tomcat裏的context.xml文件,在context 元素下添加<Loader delegate="true" />後端

相關文章
相關標籤/搜索