傳統“長輪詢”實現web端即時通訊的問題
websocket出現之前,web端為了實現即時通訊,所用的技術都是ajax輪詢(polling)。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出http request,然后由服務器返回最新的數據給客服端的瀏覽器。這種傳統的http request 的模式帶來很明顯的缺點 – 瀏覽器需要不斷的向服務器發出請求,然而http request 的header是非常長的,里面包含的數據可能只是一個很小的值,這樣會占用很多的帶寬。
而比較新的技術去做輪詢的效果是comet , 但這種技術雖然可達到全雙工通信,依然需要發出請求。
websocket 技術概覽
在 websocket api,瀏覽器和服務器只需要要做一個握手的動作,然后,瀏覽器和服務器之間就形成了一條快速通道。兩者之間就直接可以數據互相傳送,改變了原有的b/s模式。
websocket技術應用的典型架構:
websocket的技術原理:
介紹了基礎知識,下面開始本文的正文內容:
c# websocket及時通信協議的實現
1:websocket有java、nodejs、python、php、等版本 ,我現在使用的是c3版本,服務器端是fleck。客戶端和服務器端來使用websocket的,下面開始講解如何使用:
2:在開始之前我們先來看看哪些瀏覽器支持websocket:
websocket服務器支持:
3:接下來我們使用的是c#控制臺程序來實現客戶端直接通信的實施推送第一步服務器端:
打開vs2015 創建項目webshoufa(如下圖)
服務器端示例展示:
打開主程序入庫program.cs
寫入主要鏈接推送代碼如下展示
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
flecklog.level = loglevel.debug; var allsockets = new list<iwebsocketconnection>(); var server = new websocketserver( "ws://0.0.0.0:7181" ); server.start(socket => { socket.onopen = () => { console.writeline( "open!" ); allsockets.add(socket); }; socket.onclose = () => { console.writeline( "close!" ); allsockets.remove(socket); }; socket.onmessage = message => { console.writeline(message); allsockets.tolist(). foreach (s => s.send( "echo: " + message)); }; }); |
以上代碼:尤為重要的注意【fleck】我們此次實例中服務端使用的是fleck如下解釋:
fleck是c#中的一個websocket服務器實現。從nugget項目分支出來,fleck不需要繼承,容器或其他引用。代碼示例如下(以下是一個將回顯給客戶端的例子。),在實現之前.net平臺必須是在4.5之上才能運行,
上面開始已經提到。例子中定義引用websocketserver服務寫入端口路勁,格式方法是固定的。參照寫入即可。
實例代碼1如下
1
2
3
4
5
6
7
|
var server = new websocketserver( "ws://localhost:7181" ); server.start(socket => { socket.onopen = () => console.writeline( "open!" ); socket.onclose = () => console.writeline( "close!" ); socket.onmessage = message => socket.send(message); }); |
實例代碼2如下(安全秘鑰版)
1
2
3
4
5
6
|
ar server = new websocketserver(“ wss: //0.0.0.0:8431 ”); server.certificate = new x509certificate2(“ mycert.pfx ”); server.start(socket => { // ...用法正常 }); |
開始觸發server.start業務輸出代碼,以上兩部分實例代碼輸出一樣的區別在于啟用安全連接需要兩件事情:使用該方案wss代替ws,并將fleck指向包含公鑰和私鑰的x509證書。
細可以參考官網api:https://github.com/statianzo/fleck (本地下載)
接下來寫入觸發鍵盤響應代碼:如下所示
1
2
3
4
5
6
7
8
9
|
var input = console.readline(); while (input != "exit" ) { foreach (var socket in allsockets.tolist()) { socket.send(input); } input = console.readline(); } |
代碼解析:上述定義input =console.readline();
由第一段輸出參數
在input不為空的情況下給予下一次事件發生。
在此完成服務器端示例開發。
客戶端頁面請求端展示(瀏覽器端)
1:新建客戶端項目,以web頁面或者webform頁面均可。
2:我的示例是以webform來創建如下圖展示:
在此,我們只實現數據實時交互展示,如需要數據存儲業務,需要在進行后臺編碼。
3:前段代碼展示:
js詳解部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
< script type = "text/javascript" > var start = function () { var inc = document.getelementbyid('incomming'); var wsimpl = window.websocket || window.mozwebsocket; var form = document.getelementbyid('sendform'); var input = document.getelementbyid('sendtext'); inc.innerhtml += "connecting to server ..< br />"; // 創建新的websocket新連接端口為7181 window.ws = new wsimpl('ws://localhost:7181/'); // 當數據從服務器服務中心發送后,繼續向下運行過程 ws.onmessage = function (evt) { inc.innerhtml += evt.data + '< br />'; }; // 當鏈接對象找到服務端成功對接后,提示正常打開 ws.onopen = function () { inc.innerhtml += '.. connection open< br />'; }; // 當鏈接對象未找找到服務端成功對接后,提示打開失敗,別切單項關閉 ws.onclose = function () { inc.innerhtml += '.. connection closed< br />'; } form.addeventlistener('submit', function (e) { e.preventdefault(); var val = input.value; ws.send(val); input.value = ""; }); } window.onload = start; </ script > |
注意:以上示例代碼片段中window.ws = new wsimpl('ws://localhost:7181/');
中ws關鍵定義。
啟用安全連接需要兩件事情:使用該方案wss代替ws,并將fleck指向包含公鑰和私鑰的x509證書。
并使用window.onload = start;
函數。
注意:
一.將腳本代碼放在網頁的底端,這樣在運行腳本代碼的時候,可以確保要操作的對象已經加載完成。
二.通過window.onload
來執行腳本代碼。
有需要了解window.onload
在js中函數中的用法詳細可參考:
第二段代碼:調用控件實體進行事件觸發:
1
2
3
4
5
6
7
8
9
10
11
|
< body > < form id = "sendform" > < input id = "sendtext" placeholder = "text to send" /> </ form > < pre id = "incomming" ></ pre > </ body > |
以上是客戶端web頁面訪問進行實施數據推送的頁面開發完成。
好了,到了這里將兩個項目生成無誤之后逐個啟動不分順序,注意需要都啟動方可進行測試驗證:如下圖效果。
啟動客戶端頁面和控制臺程序(然后刷新下客戶端頁面即可)
在客戶端和服務器端交互時輸入:你好,高峰或者xxxx信息,幾乎在零誤差時間內服務器端收到數據。然后也可在服務器端窗口輸入信息,例如:你是不是要去阿拉善出差?
成功了,呵呵,是不是很神奇,現在可以添加自己喜歡的接口業務邏輯在里面了,是不是覺得前后臺通信變得簡單了?強不強大?爽不爽!!!!
ok,到此我們就結束了這里的教程,此次重點講述了以下兩點開發組套,大家在開發過程中尤為重視:
1:.net 4.5 添加了websocket
2:服務端:
1
2
3
4
5
6
|
var listener = new httplistener(); listener.prefixes.add( "http://*:8080/" ); listener.start(); var context = await listener.getcontextasync(); var wscontext = await context.acceptwebsocketasync( null ); var ws = wscontext.websocket; |
3:客戶端:
1
2
|
var ws = new clientwebsocket(); await ws.connectasync( new uri( "ws://127.0.0.1:8080" ),cancellationtoken.none); |
ok,感謝大家看完小示例,有不足之處還請大家多多指教,共同探討,以下將實例代碼程序上傳進來供大家參考,完善。
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:http://www.cnblogs.com/inthere/p/7878347.html