websocket基礎:websocket使用示例及學習資料
介紹
Web Sockets的目標是在一個單獨的持久連線上提供全雙工、雙向通訊。在JavaScript中建立了Web Socket之後,會有一個HTTP請求傳送到瀏覽器以發起連線。在取得伺服器響應後,建立的連線會使用HTTP升級從HTTP協議交換為Web Socket協議。也就是說,使用標準的HTTP伺服器無法實現Web Sockets,只有支援這種協議的專門伺服器才能正常工作。
由於Web Sockets使用了自定義的協議,所以URL模式也略有不同。未加密的連線不再是http://,而是ws://;加密的連線也不是https://,而是wss://。在使用Web Socket URL時,必須帶著這個模式,因為將來還有可能支援其他模式。
使用自定義協議而非HTTP協議的好處是,能夠在客戶端和伺服器之間傳送非常少量的資料,而不必擔心HTTP那樣位元組級的開銷。由於傳送的資料包很小,因此Web Sockets非常適合移動應用。畢竟對移動應用而言,頻寬和網路延遲都是關鍵問題。使用自定義協議的缺點在於,指定協議的時間比制定JavaScript API的時間還要長。
示例教程
學習WebSocket最好的資料就是官方給的demo,比如tomcat容器給的examples。無論你的tomcat中有沒有examples示例檔案,啟動tomcat伺服器後,開啟localhost:8080都能看到這樣的部分:
圈紅的部分就是tomcat給出的該容器支援的API的示例。點開連線,可能會看到
說明在你的tomcat中沒有examples示例專案。也就是在tomcat安裝目錄下的webapps資料夾中沒有examples資料夾,到官網上下載一份對應版本的tomcat,解壓後複製examples資料夾到TOMCAT_HOME(安裝目錄)下的webapps中,重啟伺服器,再次訪問localhost:8080,點選Examples連線,可以看到在頁面中有這樣的幾個示例專案:
第三個就是學習WebSocket要用到的示例專案,可以到資料夾中檢視java原始碼,位置:TOMCAT_HOME/webapps/examples/WEB-INFO/classes/websocket,xhtml程式碼:TOMCAT_HOME/webapps/examples/websocket。
沒有下載examples檔案可以線上檢視tomcat示例:http://www.4371.cn/
視訊學習下載(尚學堂-高明鑫-websocket-01-08)
視訊:百度雲網盤連結:http://pan.baidu.com/s/1bp9imsv 密碼:rokz
示例專案下載
自己也將tomcat examples中的兩個示例專案匯入了eclipse中,環境:JDK1.7,tomcat7.maven+eclipse
已經打包,下載解壓後將websocket\target下的websocket.war包直接放到tomcat下的webapps中,啟動伺服器後訪問http://localhost:8080/websocket/websocket/echo/echo.html
和http://localhost:8080/websocket/websocket/chat/chat.html即可,分別是tomcat的echo和chat示例。環境已經搭建好可以直接執行。
使用講解
使用websocket完成的目標是在客戶和伺服器之間建立一個雙向可通的通道。既然是雙向的,那麼就要求要對伺服器和客戶端兩部分進行程式設計。
伺服器
伺服器中的程式碼websocket部分也分為兩部分,一個是配置,另一個是服務。
配置的話比較簡單,就是在專案啟動時檢測websocket服務類。在tomcat的示例中有介面式的websocket也有註解式的websocket兩種示例。在上面自己整理的專案中只有註解式的,感覺註解比較簡潔。
註解式的實現配置檔案只需實現javax.websocket.server.ServerApplicationConfig介面即可,是websocket的核心配置類,該介面也只有兩個需要實現的方法,程式碼:
public class WSCoreConfig implements ServerApplicationConfig{
public Set<ServerEndpointConfig> getEndpointConfigs(
Set<Class<? extends Endpoint>> scanned) {
return null;
}
//註解的方式
public Set<Class<?>>getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
System.err.println("===== START CONFIG=====\nscannedsize:" + scanned.size());
return scanned;
}
}
對於服務,就是用來處理通道各種狀態(開啟、異常、關閉)及收發資訊的類,用來完成websocket的基本操作:
1. 開啟連線
2. 伺服器端接收資料
3. 伺服器端給客戶端傳送資料
4. 處理異常
主要需要用到的註解:@OnOpen、@OnClose、@OnMessage、@OnError
分別對應通道開啟、通道關閉、收發資訊、異常。
簡單的示例程式碼也是比較簡單的:
@ServerEndpoint(value="/ws/echo/echoServer/chat")
public class ChatAnnotation {
private static final String GUEST_PREFIX = "Guest";
private static final AtomicInteger connectionIds = new AtomicInteger(0);
private static final Set<ChatAnnotation> connections =
new CopyOnWriteArraySet<ChatAnnotation>();
private final String nickname;
private Session session;
public ChatAnnotation() {
nickname = GUEST_PREFIX + connectionIds.getAndIncrement();
}
@OnOpen
public void start(Session session) {
this.session = session;
connections.add(this);
String message = String.format("* %s %s", nickname, "has joined.");
broadcast(message);
}
@OnClose
public void end() {
connections.remove(this);
String message = String.format("* %s %s",
nickname, "has disconnected.");
broadcast(message);
}
@OnMessage
public void incoming(String message) {
broadcast(nickname + " : " + message);
}
@OnError
public void onError(Throwable t) throwsThrowable {
}
private static void broadcast(String msg) {
for (ChatAnnotation client : connections) {
try {
synchronized (client) {
client.session.getBasicRemote().sendText(msg);
}
} catch (IOException e) {
connections.remove(client);
try {
client.session.close();
} catch (IOException e1) {
// Ignore
}
String message = String.format("* %s %s",
client.nickname, "has been disconnected.");
broadcast(message);
}
}
}
}
程式碼講解:
開始的@ServerEndpoint(value="/ws/echo/echoServer/chat")表示該服務類的URI。在前臺連線該服務時用到的url為:ws://localhost:8080 /websocket/ws/echo/echoServer/chat。該類中定義了一個靜態方法broadcast(),為廣播客戶端傳送來的資訊。client.session.getBasicRemote().sendText(msg);該程式碼行為傳送資訊的主要程式碼,向客戶端傳送訊息。
該類中的其它幾個方法的宣告上可以看到@onXXX,表示該方法在何時得到呼叫。
客戶端
客戶端的程式碼主要是websocket物件。要建立WebSocket,先例項一個WebSocket物件並傳入要連線的URL:
var socket = newWebSocket(“ws://localhost:8080 /websocket/ws/echo/echoServer/chat”);
注意,必須給WebSocket建構函式傳入絕對URL。同源策略對WebSockets不適用,因此可以通過它開啟到任何站點的連線。至於是否會與某個域中的頁面通訊,則完全取決於度武器。(通過握手資訊就可以知道請求來自何方。)
例項化了WebSocket物件後,瀏覽器就會馬上嘗試建立連線。WebSocket有一個表示當前狀態的readState屬性,如下所示:
WebSocket.OPENING(0):正在建立連線。
WebSocket.OPEN(1):已經建立鍵連線。
WebSocket.CLOSING(2):正在關閉連線。
WebSocket.CLOSE(3):已經關閉連線。
WebSocket沒有readystatechange事件;不過,它有其他事件,對應著不同的狀態。readyState的值永遠從0開始。
要關閉Web Socket連線,可以在任何時候呼叫close()方法。
socket.close();
傳送和接收資料
Web Socket開啟之後,就可以通過連線傳送和接收資料。要向伺服器傳送資料,使用send()方法並傳入任意字串,例如:
var socket = newWebSocket(“ws://localhost:8080 /websocket/ws/echo/echoServer/chat”);
socket.send(“HelloWorld”);
因為Web Socket只能通過連線傳送純文字資料,所以對於複雜的資料結構,在通過連線傳送之前,必須進行序列化。
當服務端發來訊息時,WebSocket物件就會觸發message事件。這個事件與其他傳遞訊息的協議類似,也是把返回的資料儲存在event.data屬性中。
其他事件
WebSocket物件還有其他三個事件,在連續生命週期的不同階段觸發。
open:在成功建立連線時觸發。
error:在發生錯誤時觸發,連線不能持續。
close:在連線關閉時觸發。
客戶端JS程式碼:
var ws = null;
function setConnected(connected) {
document.getElementById('connect').disabled = connected;
document.getElementById('disconnect').disabled = !connected;
document.getElementById('echo').disabled = !connected;
}
function connect() {
var target = document.getElementById('target').value;
if (target == '') {
alert('Please select server side connection implementation.');
return;
}
if ('WebSocket' in window) {
ws = new WebSocket(target);
} else if ('MozWebSocket' in window) {
ws = new MozWebSocket(target);
} else {
alert('WebSocket is not supported by this browser.');
return;
}
ws.onopen = function () {
setConnected(true);
log('Info: WebSocket connection opened.');
};
ws.onmessage = function (event) {
log('Received: ' + event.data);
};
ws.onclose = function (event) {
setConnected(false);
log('Info: WebSocket connection closed, Code: ' + event.code + (event.reason == "" ? "" : ", Reason: " + event.reason));
};
}
function disconnect() {
if (ws != null) {
ws.close();
ws = null;
}
setConnected(false);
}
function echo() {
if (ws != null) {
var message = document.getElementById('message').value;
log('Sent: ' + message);
ws.send(message);
} else {
alert('WebSocket connection not established, please connect.');
}
}
function updateTarget(target) {
if (window.location.protocol == 'http:') {
document.getElementById('target').value = 'ws://' + window.location.host + target;
} else {
document.getElementById('target').value = 'wss://' + window.location.host + target;
}
}
function log(message) {
var console = document.getElementById('console');
var p = document.createElement('p');
p.style.wordWrap = 'break-word';
p.appendChild(document.createTextNode(message));
console.appendChild(p);
while (console.childNodes.length > 25) {
console.removeChild(console.firstChild);
}
console.scrollTop = console.scrollHeight;
}
document.addEventListener("DOMContentLoaded", function() {
// Remove elements with "noscript" class - <noscript> is not allowed in XHTML
var noscripts = document.getElementsByClassName("noscript");
for (var i = 0; i < noscripts.length; i++) {
noscripts[i].parentNode.removeChild(noscripts[i]);
}
}, false);
程式碼講解:
首先定義了一個名為ws的全域性變數,建立WebSocket例項時傳入了URL引數:
ws = new WebSocket(target);
方法connect()為關鍵方法,例項WebSocket物件,並指定了open、message、error、close事件的處理程式。在該方法中做了瀏覽器相容處理:
if ('WebSocket' in window) {
ws = new WebSocket(target);
} else if ('MozWebSocket' in window) {
ws = new MozWebSocket(target);
} else {
alert('WebSocket is not supported by thisbrowser.');
return;
}
其他方法說明:
setConnected()設定頁面按鈕的狀態(已經連線時,連線按鈕禁用、啟用斷開連線按鈕和訊息按鈕……)
disconnect()斷開連線:ws.close();
echo()列印訊息到頁面。
javax.websocketAPI關於介面式的websocket可參考tomcat官方示例,若在學習或專案搭建過程中有什麼問題可評論或郵件我的CSDN,以共同進步。
相關推薦
websocket基礎:websocket使用示例及學習資料
介紹 Web Sockets的目標是在一個單獨的持久連線上提供全雙工、雙向通訊。在JavaScript中建立了Web Socket之後,會有一個HTTP請求傳送到瀏覽器以發起連線。在取得伺服器響應後,建立的連線會使用HTTP升級從HTTP協議交換為Web Socket協議。
0基礎怎麼學習大資料,大資料學習路線及學習資料
資料科學並沒有一個獨立的學科體系,統計學,機器學習,資料探勘,資料庫,分散式計算,雲端計算,資訊視覺化等技術或方法來對付資料,一起來看看資料大咖的分享。 但從狹義上來看,我認為資料科學就是解決三個問題: 1. data pre-processing;(資料預處理) 2.
二、Go學習筆記:HelloWorld示例及工作目錄
瞭解GOPATH目錄下的目錄結構 ,對於初學者而言只需瞭解src就行。 |- WorkSpace |- src |- pkg |- bin 本系列學習筆記部分改編自Go語言中文網,其中的教程是翻譯自國外教程,其中有一些語句翻譯不通難以理解。故
入門機器(深度)學習的書籍及學習資料推薦
原理 .com 部分 nump 個人學習 概率論 並且 實驗 matplot (第一次寫博客,如有什麽地方寫得不對的,或者意見相左的,還請見諒!) 工作了一段時間,又重新回來讀書(本科計算機專業,第一個研究生是商科,現讀回了計算機專業)了,最開始想著走APP研發路線的,但是
吐血整理:50G區塊鏈學習資料全免費,拿走不謝!
2018年了,你還不瞭解區塊鏈? 隨著比特幣為代表的數字貨幣的暴漲,區塊鏈迅速進入了我們的視野。 但是作為一項新興的技術,好多人想學習卻苦於沒有合適的渠道。 小編最近熬夜整理了50G關於區塊鏈的資料包,全是乾貨,從小白入門到老韭菜都需要的資料,全部無償奉獻給大家。 1、區塊鏈
nodejs環境遇到的問題及學習資料
安裝nvm https://github.com/coreybutler/nvm-windows/releases 下載安裝 修改settings.txt root: D:\dev\nvm path: D:\dev\nodejs node mirror:
MyBatis概述及學習資料整理
MyBatis這個名字真的是如雷貫耳,但一直沒仔細研究過,最近閒來無事,收集了些資料並寫了些Demo,算是有了個初步的認識。必須得說MyBatis的相關資料確實不算多,收集的過程也花了我不少的時間,還好框架還算易用,沒有太大的學習難度。 一、MyBatis介紹 介紹啊介紹,說說MyBatis的前世今生,這個
mongoDB基礎篇——NoSQL特性及MongoDB資料查詢
本文將進一步介紹MongoDB的特點,深入瞭解面向集合操作的資料庫增刪改查。 一、MongoDB特性 結合傳統關係型資料庫,我們從以下四個方面再度深入認識NoSQL資料庫,以MongoDB為
零基礎入門黑客,附學習資料打包全送
今天心血來潮給大家寫個新手到黑客入門的路徑圖【附全部學習資料下載】! 入門介紹: 說到黑客大家可能覺得很神祕,其實我們說的的黑客是白帽子黑客,就是去尋找網站、系統、軟體等漏洞並幫助廠商修復的人,剛入門的黑客大部分從事滲透工作,而滲透大部分屬於web安全方向,就是利用漏洞來
揭祕“撩”大資料的正確姿勢:生動示例解說大資料“三駕馬車”
谷歌三駕馬車如何解決海量資料儲存與計算問題。 我是我:“緣起於美麗,相識於邂逅,廝守到白頭!” 眾聽眾:“呃,難道今天是要分享如何作詩?!” 我是我:“大家不要誤會,今天主要的分享不是如何作詩,而是《揭祕:‘撩’大資料的正確姿勢》,下面進入正題。” 話說當下技術圈的朋友,一起聚個
程式設計師必備基礎:Git 命令全方位學習
## 前言 掌握Git命令是每位程式設計師必備的基礎,之前一直是用smartGit工具,直到看到大佬們都是在用Git命令操作的,回想一下,發現有些Git命令我都忘記了,於是寫了這篇博文,複習一下~ > https://github.com/whx123/JavaHome **公眾號:撿田螺的小男孩*
SQL 基礎學習: 和深度學習資料
原子 rom 深度學習 允許 important href system 持久 cti SQL is a standard language for storing, manipulating and retrieving data in databasee. 關系型數據庫
小甲魚零基礎入門python第005講課後測試題及答案:閒聊之python的資料型別
0.在 Python 中, int 表示整型, 那你還記得 bool 、 float 和 str 分別表示什麼嗎? bool :布林型,ture代表1,false代表0;float:浮點型;str:字串 1. 你知道為什麼布林型別 (bool) 的 True 和 False 分別用 1 和 0
大資料技術學習筆記之hive框架基礎1-基本架構及環境部署
一、hive的介紹及其發展 "27.38.5.159" "-" "31/Aug/2015:00:04:37 +0800" "GET /course/view.php?id=27 HTTP/1.1" "303" "440" - "http://www.micro.com/user.php?act
大資料技術學習筆記之Hadoop框架基礎1-Hadoop介紹及偽分散式部署
一、學習建議 -》學習思想 -》設計思想:分散式 -》資料採集
大資料技術學習筆記之Hadoop框架基礎2-MapReduce程式設計及執行流程
一、回顧 -》hadoop的功能? -》海量資料儲存和海量計算問題 -》分散式檔案儲存框架hdfs和
Java基礎:&與&&,|與| |的聯絡與區別(詳解及示例)
&與&& 的聯絡與區別 一、&與&&的相同點 &與&& 都可作為 邏輯“與”的運算,即當運算子兩邊表示式結果都為True時,運算結果返回True;否則當某一表達式為False時,運算結果返回False 。
c++基礎:資料型別轉換及處理(二)檔案路徑擷取檔名
繼續昨天未寫完的...我是初學者,如果覺得太簡單,勿噴,如果有什麼錯誤之處,請指出,多謝~! 今天整理了寫的根據檔案路徑擷取檔名相關程式碼,主要包含替換路徑中的“/”為“'\”,然後根據“\”擷取最後的字串,即檔名 一、字串完全替換 以下方法可以替換掉
c++基礎:資料型別轉換及處理(一)string轉wstring及檔案拷貝
使用java太長時間,已經習慣了其資料型別轉換及處理的便捷。但是,現在使用c++,不得不去面對其資料型別轉換,以及相關的處理。瞬間感覺奔潰,一天中,很多時間都交給度娘了... 檔案拷貝 本來很方便,提供了CopyFile,但是看到入參,瞬間崩潰,普通字串不行
TensorFlow遊樂場及神經網路簡介,我以《Tensorflow:實戰Google深度學習框架》為主,基礎最重要
轉載:https://blog.csdn.net/broadview2006/article/details/80128755 本文將通過TensorFlow遊樂場來快速介紹神經網路的主要功能。TensorFlow遊樂場(http://playground.tensorflow.org)是一個通