日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【转】WebSocket初探

發(fā)布時(shí)間:2023/12/10 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转】WebSocket初探 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

定義:

遵循RFC6544協(xié)議的通信協(xié)議。Webcoket協(xié)議和http協(xié)議屬于并行關(guān)系,但是websocket是以http協(xié)議為基礎(chǔ)開(kāi)發(fā)出來(lái)的(微軟用IhttpHandler接口中同時(shí)處理這兩種協(xié)議),同時(shí)他們都是以TCP協(xié)議為基礎(chǔ)。可以進(jìn)行雙向通信、持久化通信。Http是單向通信協(xié)議、無(wú)狀態(tài)通信。

websocket協(xié)議(握手部分):

GET /chat HTTP/1.1
Host: http://server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin:?http://example.com

比http握手多了幾個(gè)部分:

Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

這幾個(gè)部分告訴服務(wù)器,該請(qǐng)求是Webcoket,不是http了。

接收的數(shù)據(jù)

GET /chat HTTP/1.1
Host:?http://example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

發(fā)送的數(shù)據(jù)

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

?

服務(wù)端:

  • 使用第三方的Fleck庫(kù),建議采用吧,比較方便。
  • 使用第三方的websocketsharp庫(kù),不方便服務(wù)端主動(dòng)推送數(shù)據(jù)到客戶端。
  • 自己按照RFC6544協(xié)議,打包協(xié)議頭+socket API庫(kù),收發(fā)數(shù)據(jù)。
  • 使用IIS8.0以上可以處理websocket請(qǐng)求:
namespace SimpleWebSocketApplication { public class WebSocketHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { //Checks if the query is WebSocket request. if (context.IsWebSocketRequest) { //If yes, we attach the asynchronous handler. context.AcceptWebSocketRequest(WebSocketRequestHandler); } } public bool IsReusable { get { return false; } } //Asynchronous request handler. public async Task WebSocketRequestHandler(AspNetWebSocketContext webSocketContext) { //Gets the current WebSocket object. WebSocket webSocket = webSocketContext.WebSocket; /*We define a certain constant which will represent size of received data. It is established by us and we can set any value. We know that in this case the size of the sent data is very small. */ const int maxMessageSize = 1024; //Buffer for received bits. var receivedDataBuffer = new ArraySegment<Byte>(new Byte[maxMessageSize]); var cancellationToken = new CancellationToken(); //Checks WebSocket state. while (webSocket.State == WebSocketState.Open) { //Reads data. WebSocketReceiveResult webSocketReceiveResult = await webSocket.ReceiveAsync(receivedDataBuffer, cancellationToken); //If input frame is cancelation frame, send close command. if (webSocketReceiveResult.MessageType == WebSocketMessageType.Close) { await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, cancellationToken); } else { byte[] payloadData = receivedDataBuffer.Array.Where(b => b != 0).ToArray(); //Because we know that is a string, we convert it. string receiveString = System.Text.Encoding.UTF8.GetString(payloadData, 0, payloadData.Length); //Converts string to byte array. var newString = String.Format("Hello, " + receiveString + " ! Time {0}", DateTime.Now.ToString()); Byte[] bytes = System.Text.Encoding.UTF8.GetBytes(newString); //Sends data back. await webSocket.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Text, true, cancellationToken); } } } } }
  • 使用TcpListener類庫(kù),不能使用httpListener類庫(kù),,創(chuàng)建監(jiān)聽(tīng),并將發(fā)送的數(shù)據(jù)按RFC6544協(xié)議打包。
(創(chuàng)建監(jiān)聽(tīng))
class Server {
public static void Main() {
TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 80);

server.Start();
Console.WriteLine("Server has started on 127.0.0.1:80.{0}Waiting for a connection...", Environment.NewLine);

TcpClient client = server.AcceptTcpClient();

Console.WriteLine("A client connected.");
}
}
(接收數(shù)據(jù))
TcpClient client = server.AcceptTcpClient();

Console.WriteLine("A client connected.");

NetworkStream stream = client.GetStream();

while(client.Available < 3)
{
// wait for enough bytes to be available
}
//enter to an infinite cycle to be able to handle every change in stream
while (true) {
while (!stream.DataAvailable);

Byte[] bytes = new Byte[client.Available];

stream.Read(bytes, 0, bytes.Length);
}
(打包發(fā)送的數(shù)據(jù))
if (new System.Text.RegularExpressions.Regex("^GET").IsMatch(data))
{
const string eol = "\r\n"; // HTTP/1.1 defines the sequence CR LF as the end-of-line marker

Byte[] response = Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" + eol
+ "Connection: Upgrade" + eol
+ "Upgrade: websocket" + eol
+ "Sec-WebSocket-Accept: " + Convert.ToBase64String(
System.Security.Cryptography.SHA1.Create().ComputeHash(
Encoding.UTF8.GetBytes(
new System.Text.RegularExpressions.Regex("Sec-WebSocket-Key: (.*)").Match(data).Groups[1].Value.Trim() + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
)
)
) + eol
+ eol);

stream.Write(response, 0, response.Length);
}

客戶端:

  • html5的JS庫(kù)
  • Fleck庫(kù)
  • websocketsharp庫(kù)
  • 微軟自己的wensocketclient庫(kù)
  • 自己按照RFC6544協(xié)議,打包協(xié)議頭+socket API庫(kù),收發(fā)數(shù)據(jù)

總結(jié)

以上是生活随笔為你收集整理的【转】WebSocket初探的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。