程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java後端Tomcat完成WebSocket實例教程

Java後端Tomcat完成WebSocket實例教程

編輯:關於JAVA

Java後端Tomcat完成WebSocket實例教程。本站提示廣大學習愛好者:(Java後端Tomcat完成WebSocket實例教程)文章只能為提供參考,不一定能成為您想要的結果。以下是Java後端Tomcat完成WebSocket實例教程正文


一.WebSocket簡略引見

WebSocket protocol 是HTML5一種新的協定。它完成了閱讀器與辦事器全雙工通訊(full-duplex)。一開端的握手須要借助HTTP要求完成握手。

  跟著互聯網的成長,傳統的HTTP協定曾經很難知足Web運用日趨龐雜的需求了。最近幾年來,跟著HTML5的出生,WebSocket協定被提出,它完成了閱讀器與辦事器的全雙工通訊,擴大了閱讀器與辦事真個通訊功效,使辦事端也能自動向客戶端發送數據。

WebSocket配景

在閱讀器中經由過程http僅能完成單向的通訊,comet可以必定水平上模仿雙向通訊,但效力較低,並須要辦事器有較好的支撐; flash中的socket和xmlsocket可以完成真實的雙向通訊,經由過程 flex ajax bridge,可以在javascript中應用這兩項功效. 可以預感,假如websocket一旦在閱讀器中獲得完成,將會替換下面兩項技巧,獲得普遍的應用.面臨這類狀態,HTML5界說了WebSocket協定,能更好的節儉辦事器資本和帶寬並到達及時通信。

在JavaEE7中也完成了WebSocket協定。

  我們曉得,傳統的HTTP協定是無狀況的,每次要求(request)都要由客戶端(如 閱讀器)自動提議,辦事端停止處置後前往response成果,而辦事端很難自動向客戶端發送數據;這類客戶端是自動方,辦事端是主動方的傳統Web形式 關於信息變更不頻仍的Web運用來講形成的費事較小,而關於觸及及時信息的Web運用卻帶來了很年夜的未便,如帶有即時通訊、及時數據、定閱推送等功效的應 用。在WebSocket標准提出之前,開辟人員若要完成這些及時性較強的功效,常常會應用調和的處理辦法:輪詢(polling)和Comet技巧。其實後者實質上也是一種輪詢,只不外有所改良。

  輪詢是最原始的完成及時Web運用的處理計劃。輪詢技巧請求客戶端以設定的時光距離周期性地向辦事端發送要求,頻仍地查詢能否有新的數據修改。顯著地,這類辦法會招致過量不用要的要求,糟蹋流量和辦事器資本。

  Comet技巧又可以分為長輪詢和流技巧。長輪詢改良了上述的輪詢技巧,減小了無用的要求。它會為某些數據設定過時時光,當數據過時後才會向辦事端發送要求;這類機制合適數據的修改不是特殊頻仍的情形。流技巧平日是指客戶端應用一個隱蔽的窗口與辦事端樹立一個HTTP長銜接,辦事端會赓續更新銜接狀況以堅持HTTP長銜接存活;如許的話,辦事端便可以經由過程這條長銜接自動將數據發送給客戶端;流技巧在年夜並發情況下,能夠會考驗到辦事真個機能。

  這兩種技巧都是基於要求-應對形式,都不算是真正意義上的及時技巧;它們的每次要求、應對,都糟蹋了必定流量在雷同的頭部信息上,而且開辟龐雜度也較年夜。

  隨同著HTML5推出的WebSocket,真正完成了Web的及時通訊,使B/S形式具有了C/S形式的及時通訊才能。WebSocket的任務流程是這 樣的:閱讀器經由過程JavaScript向辦事端收回樹立WebSocket銜接的要求,在WebSocket銜接樹立勝利後,客戶端和辦事端便可以經由過程 TCP銜接傳輸數據。由於WebSocket銜接實質上是TCP銜接,不須要每次傳輸都帶上反復的頭部數據,所以它的數據傳輸量比輪詢和Comet技巧小 了許多。本文不具體地引見WebSocket標准,重要引見下WebSocket在Java Web中的完成。

  JavaEE 7中出了JSR-356:Java API for WebSocket標准。很多Web容器,如Tomcat,Nginx,Jetty等都支撐WebSocket。Tomcat從7.0.27開端支撐 WebSocket,從7.0.47開端支撐JSR-356,上面的Demo代碼也是須要安排在Tomcat7.0.47以上的版本能力運轉。

二.WebSocket示例

2.1.新建JavaWeb測試項目

  在pom.xml中添加Jar包依附

<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>.</version>
<scope>provided</scope>
</dependency> 

  客戶端(Web主頁)代碼:

<%@ page language="java" pageEncoding="UTF-" %>
<!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:/websocket");
}
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> 

  Java Web後端代碼

package me.gacl.websocket;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
/**
* @ServerEndpoint 注解是一個類條理的注解,它的功效重要是將今朝的類界說成一個websocket辦事器端,
* 注解的值將被用於監聽用戶銜接的終端拜訪URL地址,客戶端可以經由過程這個URL來銜接到WebSocket辦事器端
*/
@ServerEndpoint("/websocket")
public class WebSocketTest {
//靜態變量,用來記載以後在線銜接數。應當把它設計成線程平安的。
private static int onlineCount = ;
//concurrent包的線程平安Set,用來寄存每一個客戶端對應的MyWebSocket對象。若要完成辦事端與單一客戶端通訊的話,可使用Map來寄存,個中Key可認為用戶標識
private static CopyOnWriteArraySet<WebSocketTest> webSocketSet = new CopyOnWriteArraySet<WebSocketTest>();
//與某個客戶真個銜接會話,須要經由過程它來給客戶端發送數據
private Session session;
/**
* 銜接樹立勝利挪用的辦法
* @param session 可選的參數。session為與某個客戶真個銜接會話,須要經由過程它來給客戶端發送數據
*/
@OnOpen
public void onOpen(Session session){
this.session = session;
webSocketSet.add(this); //參加set中
addOnlineCount(); //在線數加
System.out.println("有新銜接參加!以後在耳目數為" + getOnlineCount());
}
/**
* 銜接封閉挪用的辦法
*/
@OnClose
public void onClose(){
webSocketSet.remove(this); //從set中刪除
subOnlineCount(); //在線數減
System.out.println("有連續接封閉!以後在耳目數為" + getOnlineCount());
}
/**
* 收到客戶端新聞後挪用的辦法
* @param message 客戶端發送過去的新聞
* @param session 可選的參數
*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("來自客戶真個新聞:" + message);
//群發新聞
for(WebSocketTest item: webSocketSet){
try {
item.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
continue;
}
}
}
/**
* 產生毛病時挪用
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error){
System.out.println("產生毛病");
error.printStackTrace();
}
/**
* 這個辦法與下面幾個辦法紛歧樣。沒有效注解,是依據本身須要添加的辦法。
* @param message
* @throws IOException
*/
public void sendMessage(String message) throws IOException{
this.session.getBasicRemote().sendText(message);
//this.session.getAsyncRemote().sendText(message);
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebSocketTest.onlineCount++;
}
public static synchronized void subOnlineCount() {
WebSocketTest.onlineCount--;
}
}

1.2.運轉後果

  同時翻開Google閱讀器和火狐閱讀器停止多客戶端模仿測試,運轉後果以下:

以上內容是小編給年夜家引見的Java後端Tomcat完成WebSocket實例教程,願望對年夜家有所贊助!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved