2010-01-14 21 views
50

Tôi muốn sử dụng WebSockets trong ứng dụng Windows Forms hoặc WPF của mình. Có một .NET-control đang hỗ trợ WebSockets chưa? Hay là có bất kỳ dự án nguồn mở nào bắt đầu về nó?Có một ứng dụng WebSocket được cài đặt cho .NET không?

Giải pháp nguồn mở cho Máy khách Java hỗ trợ WebSockets cũng có thể giúp tôi.

Trả lời

20

Bây giờ, SuperWebSocket cũng bao gồm một thực hiện WebSocket client SuperWebSocket Project Homepage

triển khai .NET client khác bao gồm:

+1

Tôi không thể thấy bất kỳ điều gì trong SuperWebSocket về việc triển khai ứng dụng khách? Nó vẫn còn đó? –

+0

Trong SourceCode/mainline/Client –

+8

Máy khách trong SuperWebSocket đã được tách thành WebSocket4Net: http://websocket4net.codeplex.com/ –

1

đó là giao thức khá đơn giản. có một triển khai java here không quá khó để dịch sang C#. nếu tôi đi xung quanh để làm điều đó, tôi sẽ đăng nó lên đây ...

24

Đây là lần đầu tiên vượt qua nhanh chóng khi chuyển mã Java đó sang C#. Không hỗ trợ chế độ SSL và chỉ được kiểm tra rất nhẹ, nhưng đó là một sự khởi đầu.

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

Lưu ý rằng StringBuilder.Append (byte) không làm những gì bạn nghĩ rằng nó - nó nối thêm biểu diễn văn bản của byte vào bộ đệm. Xây dựng danh sách các byte và sau đó chuyển đổi byte đó thành một chuỗi bằng cách sử dụng Encoding.UTF8.GetString (bytes) hoạt động tốt hơn. –

+1

+1 đã làm việc cho tôi. Cuối cùng tôi đã sửa đổi 'mStream = new SslStream (mClient.GetStream());' và thêm 'mStream.AuthenicateAsClient (máy chủ);', và đó là tất cả những gì cần thiết để hỗ trợ SSL. – primo

1

Gần đây, Bridges và Labs Trung tâm Khả năng cộng tác phát hành một việc thực hiện nguyên mẫu (trong mã quản lý) của hai dự thảo đặc tả WebSockets giao thức:

draft-hixie-thewebsocketprotocol-75draft-hixie -thewebsocketprotocol-76

Nguyên mẫu có thể được tìm thấy tại HTML5 Labs. Tôi đặt vào this blog post tất cả thông tin tôi đã tìm thấy (cho đến bây giờ) và các đoạn mã về cách thực hiện điều này bằng WCF.

1

Nếu bạn muốn thứ gì đó nhẹ hơn một chút, hãy kiểm tra máy chủ C# mà một người bạn và tôi đã phát hành: https://github.com/Olivine-Labs/Alchemy-Websockets

Hỗ trợ ổ cắm web vani cũng như ổ flash web. Nó được xây dựng cho trò chơi trực tuyến của chúng tôi với trọng tâm là khả năng mở rộng và hiệu quả.

5

Có một ứng dụng khách: http://websocket4net.codeplex.com/!

+0

Tôi recommand này tôi đã làm việc với nó và phải trung thực tuyệt vời của nó. – Rushino

+0

Nhanh chóng và sạch sẽ, cảm ơn bạn đã chia sẻ. – Thomas

10

Hỗ trợ cho WebSockets là coming in .NET 4.5. Liên kết đó cũng chứa ví dụ sử dụng lớp System.Net.WebSockets.WebSocket.

+2

Từ tài liệu "việc triển khai công khai duy nhất của WebSockets của máy khách và máy chủ được hỗ trợ trên Windows 8 và Windows Server 2012" - tức là. nó sẽ không hoạt động với các phiên bản cửa sổ cũ hơn. –

0

Ngoài ra còn có giả kim thuật. http://olivinelabs.com/Alchemy-Websockets/ khá thú vị.

+0

và đó không phải là ứng dụng khách WebSocket – Shaddix

+0

Có. Có một WebSocket client lib với nó. Nhìn lại! – Rushino

+0

Tôi không thấy nó như là một lib thực sự. Có một [lớp WebSocketClient] (https://github.com/Olivine-Labs/Alchemy-Websockets/blob/master/src/Alchemy/WebSocketClient.cs) mặc dù, đúng – Shaddix

4

lựa chọn khác: XSockets.Net, có thực hiện máy chủ và máy khách.

có thể cài đặt máy chủ bằng cách:

PM> Install-Package XSockets 

hoặc cài đặt khách hàng bằng cách:

PM> Install-Package XSockets.Client 

phiên bản hiện tại: 3.0.4

Các vấn đề liên quan