2010-01-14 71 views
50

我想在我的Windows窗體或WPF應用程序中使用WebSockets。是否有.NET控件支持實現的WebSockets?還是有任何開源項目開始呢?是否有爲.NET實現的WebSocket客戶端?

支持WebSockets的Java客戶端的開源解決方案也可以幫助我。

回答

20

,SuperWebSocket還包括的WebSocket客戶端實現 SuperWebSocket Project Homepage

其他.NET客戶端實現包括:

+1

我看不到在SuperWebSocket中關於客戶端實現的任何內容?它還在嗎? – 2011-11-27 04:48:03

+0

在源代碼/主線/客戶端 – 2011-12-08 08:14:54

+8

SuperWebSocket中的客戶端已分離爲WebSocket4Net:http://websocket4net.codeplex.com/ – 2012-01-09 02:31:24

1

這是一個非常簡單的協議。有一個Java實現here,不應該太難以轉換爲C#。如果我開始這樣做,我會在這裏發佈它...

24

下面是將Java代碼移植到C#時的第一個快速入門。不支持SSL模式,只經過非常輕微的測試,但這是一個開始。

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Net; 
using System.Net.Sockets; 
using System.Text; 

public class WebSocket 
{ 
    private Uri mUrl; 
    private TcpClient mClient; 
    private NetworkStream mStream; 
    private bool mHandshakeComplete; 
    private Dictionary<string, string> mHeaders; 

    public WebSocket(Uri url) 
    { 
     mUrl = url; 

     string protocol = mUrl.Scheme; 
     if (!protocol.Equals("ws") && !protocol.Equals("wss")) 
      throw new ArgumentException("Unsupported protocol: " + protocol); 
    } 

    public void SetHeaders(Dictionary<string, string> headers) 
    { 
     mHeaders = headers; 
    } 

    public void Connect() 
    { 
     string host = mUrl.DnsSafeHost; 
     string path = mUrl.PathAndQuery; 
     string origin = "http://" + host; 

     mClient = CreateSocket(mUrl); 
     mStream = mClient.GetStream(); 

     int port = ((IPEndPoint)mClient.Client.RemoteEndPoint).Port; 
     if (port != 80) 
      host = host + ":" + port; 

     StringBuilder extraHeaders = new StringBuilder(); 
     if (mHeaders != null) 
     { 
      foreach (KeyValuePair<string, string> header in mHeaders) 
       extraHeaders.Append(header.Key + ": " + header.Value + "\r\n"); 
     } 

     string request = "GET " + path + " HTTP/1.1\r\n" + 
         "Upgrade: WebSocket\r\n" + 
         "Connection: Upgrade\r\n" + 
         "Host: " + host + "\r\n" + 
         "Origin: " + origin + "\r\n" + 
         extraHeaders.ToString() + "\r\n"; 
     byte[] sendBuffer = Encoding.UTF8.GetBytes(request); 

     mStream.Write(sendBuffer, 0, sendBuffer.Length); 

     StreamReader reader = new StreamReader(mStream); 
     { 
      string header = reader.ReadLine(); 
      if (!header.Equals("HTTP/1.1 101 Web Socket Protocol Handshake")) 
       throw new IOException("Invalid handshake response"); 

      header = reader.ReadLine(); 
      if (!header.Equals("Upgrade: WebSocket")) 
       throw new IOException("Invalid handshake response"); 

      header = reader.ReadLine(); 
      if (!header.Equals("Connection: Upgrade")) 
       throw new IOException("Invalid handshake response"); 
     } 

     mHandshakeComplete = true; 
    } 

    public void Send(string str) 
    { 
     if (!mHandshakeComplete) 
      throw new InvalidOperationException("Handshake not complete"); 

     byte[] sendBuffer = Encoding.UTF8.GetBytes(str); 

     mStream.WriteByte(0x00); 
     mStream.Write(sendBuffer, 0, sendBuffer.Length); 
     mStream.WriteByte(0xff); 
     mStream.Flush(); 
    } 

    public string Recv() 
    { 
     if (!mHandshakeComplete) 
      throw new InvalidOperationException("Handshake not complete"); 

     StringBuilder recvBuffer = new StringBuilder(); 

     BinaryReader reader = new BinaryReader(mStream); 
     byte b = reader.ReadByte(); 
     if ((b & 0x80) == 0x80) 
     { 
      // Skip data frame 
      int len = 0; 
      do 
      { 
       b = (byte)(reader.ReadByte() & 0x7f); 
       len += b * 128; 
      } while ((b & 0x80) != 0x80); 

      for (int i = 0; i < len; i++) 
       reader.ReadByte(); 
     } 

     while (true) 
     { 
      b = reader.ReadByte(); 
      if (b == 0xff) 
       break; 

      recvBuffer.Append(b);   
     } 

     return recvBuffer.ToString(); 
    } 

    public void Close() 
    { 
     mStream.Dispose(); 
     mClient.Close(); 
     mStream = null; 
     mClient = null; 
    } 

    private static TcpClient CreateSocket(Uri url) 
    { 
     string scheme = url.Scheme; 
     string host = url.DnsSafeHost; 

     int port = url.Port; 
     if (port <= 0) 
     { 
      if (scheme.Equals("wss")) 
       port = 443; 
      else if (scheme.Equals("ws")) 
       port = 80; 
      else 
       throw new ArgumentException("Unsupported scheme"); 
     } 

     if (scheme.Equals("wss")) 
      throw new NotImplementedException("SSL support not implemented yet"); 
     else 
      return new TcpClient(host, port); 
    } 
} 
+6

注意StringBuilder.Append(字節)不會做什麼你認爲它確實 - 它將字節的文本表示附加到緩衝區。構建一個字節列表,然後使用Encoding.UTF8.GetString(字節)將該字節[]轉換爲字符串效果更好。 – 2010-07-07 20:38:48

+1

+1爲我工作。我最終修改了'mStream = new SslStream(mClient.GetStream());'並添加了'mStream.AuthenicateAsClient(host);',這就是SSL支持所需要的。 – primo 2016-02-10 13:01:18

1

最近互通橋樑和實驗室中心發佈的WebSockets協議規範的兩份草案的原型實現(在託管代碼):

選秀hixie-thewebsocketprotocol-75選秀hixie -thewebsocketprotocol-76

該原型可以在HTML5實驗室找到。我在this blog post中發現了我發現的所有信息(直到現在)以及關於如何使用WCF完成這些代碼的代碼片段。現在

1

如果你想要一個更輕量級的東西,看看一個朋友和我發佈的C#服務器:https://github.com/Olivine-Labs/Alchemy-Websockets

支持香草websockets以及flash網絡套接字。它專爲我們的在線遊戲而設計,重點在於可擴展性和效率。

5

有一個客戶端實現:http://websocket4net.codeplex.com/

+0

我推薦這一款,我與它合作,說實話它的驚人。 – Rushino 2014-03-19 20:38:10

+0

快速,乾淨,謝謝你的分享。 – Thomas 2014-10-13 19:25:51

10

對WebSockets的支持是coming in .NET 4.5。該鏈接還包含一個使用System.Net.WebSockets.WebSocket類的示例。

+2

從文檔「客戶端和服務器WebSocket的唯一公共實現在Windows 8和Windows Server 2012上受支持」 - 即。它不適用於舊版本的Windows。 – 2014-05-31 05:50:08

0

還有鍊金術。 http://olivinelabs.com/Alchemy-Websockets/這很酷。

+0

和哪個不是WebSocket客戶端 – Shaddix 2014-03-18 05:56:48

+0

是的。它有一個WebSocket客戶端庫。再看一遍! – Rushino 2014-03-19 20:37:38

+0

我不認爲它實際上是一個lib。雖然有一個[WebSocketClient類](https://github.com/Olivine-Labs/Alchemy-Websockets/blob/master/src/Alchemy/WebSocketClient.cs),對 – Shaddix 2014-03-20 03:09:08

4

另一種選擇:XSockets.Net,具有實現服務器和客戶端。

可以通過安裝服務器:

PM> Install-Package XSockets 

或安裝客戶端:

PM> Install-Package XSockets.Client 

目前的版本是:3.0.4