【WebSocket No.1】實現服務端webSocket鏈接通信

前言

現階段socket通訊使用TCP、UDP協議,其中TCP協議相對來講比較安全穩定!本文也是來說解TCP爲主(恕在下學藝不精)。      javascript

下面是我的理解的tcp/ip進行通信之間的三次握手!html

1.客戶端先發送報文到服務端java

2.服務端接受到報文以後進行回覆web

3.客戶端收到回覆以後再次發送確認信息。這個時候纔是正式進行鏈接。瀏覽器

什麼是WebSocket 

WebSocket 是一種網絡通訊協議。RFC6455 定義了它的通訊標準。安全

WebSocket 是 HTML5 開始提供的一種在單個 TCP 鏈接上進行全雙工通信的協議。服務器

與傳統的HTTP協議對比:websocket

HTTP 協議是一種無狀態的、無鏈接的、單向的應用層協議。它採用了請求/響應模型。通訊請求只能由客戶端發起,服務端對請求作出應答處理。也就是說HTTP沒有辦法作到在客戶端不請求服務器的狀況下主動給客戶端發送消息。可是這種狀況有時確實咱們必須的。固然咱們在WebSocket以前咱們也是有辦法解決的,好比咱們使用輪詢技術來實現一部分的目的,可是有了WebSocket是必輪詢更加合理的解決方案。網絡

WebSocket API介紹

建立WebSocket 對象,這是全部步驟的第一步。socket

var Socket = new WebSocket(url, [protocol] );

WebSocket 對象屬性

Socket.readyState:只讀屬性 readyState 表示鏈接狀態,能夠是如下值:0 - 表示鏈接還沒有創建。1 - 表示鏈接已創建,能夠進行通訊。2 - 表示鏈接正在進行關閉。3 - 表示鏈接已經關閉或者鏈接不能打開。

Socket.bufferedAmount:只讀屬性 bufferedAmount 已被 send() 放入正在隊列中等待傳輸,可是尚未發出的 UTF-8 文本字節數。

WebSocket 事件

WebSocket 存在基本的的四個事件處理

Socket.onopen:鏈接創建時觸發

Socket.onmessage:客戶端接受到服務器發送的消息時候觸發

Socket.onerror:通許期間發生錯誤時觸發

Socket.onclose:鏈接關閉觸發,無論你主動仍是被動的

WebSocket 方法

Socket.send():發送消息給服務器

Socket.close():關閉鏈接,客戶端主動關閉。

鏈接形式:

      服務器監聽:服務器開啓服務以後,就進入了監聽客戶端鏈接狀態。此時不是指定監聽那臺客戶端那是處於一個等待狀態(不是暫停,一直處於網絡實時監聽),等待客戶端找他進行鏈接。

       客戶端鏈接:客戶端對目標服務器發起連接請求,發起請求必需要知道IP以及相應端口號。

       確認連接:這個時候服務端的監聽就起做用了,受到客戶端的請求後會響應客戶端請求,建立socket連接。在這裏須要注意連接不是一對一的,服務端會從新對請求客戶端建立新的socket服務。因此服務端仍處於監聽狀態仍能夠監聽。

代碼示例

好了以上就是一些基本介紹,主要是爲了如下的東西作鋪墊,畢竟要實現須要有socket的基礎,言歸正傳。下面開始咱們完整的webSocket練習吧!(網上有些使用插件或者類庫實現的websocket。可是咱們所講的是以socket爲基礎的)

建立服務器

別的很少少首先建立socket服務器:

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading.Tasks;
 6 using System.Net.Sockets;
 7 using System.Net;
 8 using System.Threading;
 9 using System.Text.RegularExpressions;
10 using System.Security.Cryptography;
11 
12 namespace SocketService
13 {
14     class SocketService
15     {
16         private static byte[] result = new byte[1024];
17         private static int myProt = 8885;   //端口  
18         static Socket serverSocket;  //服務器服務
19         public void Start()
20         {
21             //服務器IP地址  
22             IPAddress ip = IPAddress.Parse("127.0.0.1");
23             //socket的構造函數進行服務註冊
24             serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
25             //綁定IP地址:端口  
26             serverSocket.Bind(new IPEndPoint(ip, myProt));
27             //設定最多10個排隊鏈接請求 
28             serverSocket.Listen(10);
29             Console.WriteLine("啓動監聽{0}成功", serverSocket.LocalEndPoint.ToString());
30             //經過Clientsoket發送數據  
31             Thread myThread = new Thread(ListenClientConnect);
32             myThread.Start();
33             Console.ReadLine();
34         }
35         /// <summary>  
36         /// 監聽客戶端鏈接  
37         /// </summary>  
38         private  void ListenClientConnect()
39         {
40             while (true)
41             {
42                 Socket clientSocket = serverSocket.Accept();
43                // clientSocket.Send(Encoding.ASCII.GetBytes("Server Say Hello"));
44                 Thread receiveThread = new Thread(ReceiveMessage);
45                 receiveThread.Start(clientSocket);
46             }
47         }
48 
49         /// <summary>  
50         /// 接收消息  
51         /// </summary>  
52         /// <param name="clientSocket"></param>  
53         private  void ReceiveMessage(object clientSocket)
54         {
55             Socket myClientSocket = (Socket)clientSocket;
56             while (true)
57             {
58                 try
59                 {
60                     //經過clientSocket接收數據  
61                     int receiveNumber = myClientSocket.Receive(result);
62                     //  websocket創建鏈接的時候,除了TCP鏈接的三次握手,websocket協議中客戶端與服務器想創建鏈接須要一次額外的握手動做
63                     string msg = Encoding.UTF8.GetString(result, 0, receiveNumber);
64                     var buffer = result;
65                     if (msg.Contains("Sec-WebSocket-Key"))
66                     {
67 
68                         myClientSocket.Send(PackageHandShakeData(buffer, receiveNumber));
69 
70                        // return;
71                     }
72                     var ss = AnalyzeClientData(result, receiveNumber);
73                     Console.WriteLine("接收客戶端{0}消息{1}", myClientSocket.RemoteEndPoint.ToString(), Encoding.UTF8.GetString(result, 0, receiveNumber));
74                 }
75                 catch (Exception ex)
76                 {
77                     Console.WriteLine(ex.Message);
78                     myClientSocket.Shutdown(SocketShutdown.Both);
79                     myClientSocket.Close();
80                     break;
81                 }
82             }
83         }
84  }
85 }
View Code

 代碼註釋我已經寫的很詳細了!但願大家能看懂(哈哈)!

 看到這裏有些聰明的網友可能發現問題了!或者操做過可是沒有成功的也看出了不一樣。沒有錯,在這裏我要說明的一點是有些websocket與socket有點不一樣的就是他的握手的首次信息以及返回信息是須要特定格式的。

也就是所謂的響應頭域須要特殊處理。在不作相對應的響應處理瀏覽器會報「握手不成功」的錯誤!

參考網址:http://www.cnblogs.com/smark/archive/2012/11/26/2789812.html 

若是初步同窗沒有看明白請移至另外一篇博客,詳細封裝了此方法解決此錯誤。(方便有些同窗查找錯誤找不到解決方法,由於鄙人也是搞了一上午纔有幸發現此問題,還望海涵)

最後咱們只須要在主方法進行調用開啓服務

此時服務端代碼大功告成!下面咱們使用js來進行請求就能夠了。

客戶端

下面附送html建議代碼也能夠去w3c查看教程:

html代碼:

    <body>
        <a href="javascript:WebSocketTest()">運行 WebSocket</a>
        <a href="javascript:webSocketClose()">關閉WebSocket</a>
        <div id="look" class="m">

        </div>
        <input id="message">
        <a href="javascript:send()">發送消息</a>
    </body>

javascript代碼:

var ws;

function WebSocketTest() {
    if("WebSocket" in window) {
        alert("您的瀏覽器支持 WebSocket!");

        // 打開一個 web socket
        ws = new WebSocket("ws://127.0.0.1:8885");

        ws.onopen = function() {
            // Web Socket 已鏈接上,使用 send() 方法發送數據
            ws.send("發送數據");
            alert("數據發送中...");
        };

        ws.onmessage = function(evt) {
            var received_msg = evt.data;
            document.getElementById("look").html+=received_msg;
            alert("數據已接收...");
        };

        ws.onclose = function() {
            // 關閉 websocket
            alert("鏈接已關閉...");
        };
    } else {
        // 瀏覽器不支持 WebSocket
        alert("您的瀏覽器不支持 WebSocket!");
    }
}

function webSocketClose() {
ws.close();
alert("關閉了通信")
}
function send(){
    var msg= document.getElementById("message").value;
    if(msg==""||msg==undefined){
        alert("請填寫發送內容!")
        return;
    }
    ws.send("1111111111");
    alert("發送了消息")
}
View Code

最後附上運行截圖:

 

好了以上就是webSocket的一些基礎介紹和簡單的代碼示例。

下一篇在此基礎上完善成一個聊天示例:【WebSocket No.2】WebSocket和Socket實現聊天羣發

相關文章
相關標籤/搜索