2010-01-14 13 views
50

Vorrei utilizzare WebSockets nei miei Windows Form o WPF-application. Esiste un controllo .NET che supporta ancora WebSockets implementato? O è stato avviato un progetto open source?Esiste un client WebSocket implementato per .NET?

Una soluzione open source per un client Java che supporta WebSockets potrebbe anche aiutarmi.

risposta

20

Ora, SuperWebSocket include anche un client di attuazione WebSocket SuperWebSocket Project Homepage

Altre implementazioni .NET client includono:

+1

Non riesco a vedere nulla in SuperWebSocket sull'implementazione di un client? È ancora lì? –

+0

In SourceCode/mainline/Client –

+8

Il client in SuperWebSocket è stato separato in WebSocket4Net: http://websocket4net.codeplex.com/ –

1

è un protocollo piuttosto semplice. c'è un'implementazione java here che non dovrebbe essere troppo difficile da tradurre in C#. se riesco a farlo, lo posterò qui ...

24

Ecco un primo passaggio veloce al porting di quel codice Java a C#. Non supporta la modalità SSL ed è stato testato solo leggermente, ma è un inizio.

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

noti che StringBuilder.Append (byte) non fa quello che si pensa di sì - aggiunge la rappresentazione testuale del byte al buffer. Costruire un elenco di byte e quindi convertire quel byte [] in una stringa usando Encoding.UTF8.GetString (byte) funziona meglio. –

+1

+1 ha funzionato per me. Ho finito con la modifica di 'mStream = new SslStream (mClient.GetStream());' e aggiungendo 'mStream.AuthenicateAsClient (host);', e questo era tutto ciò che era necessario per il supporto SSL. – primo

1

Recentemente l'interoperabilità Ponti e Labs Center ha pubblicato un prototipo di attuazione (in codice gestito) di due bozze di specifiche del protocollo WebSocket:

progetto-hixie-thewebsocketprotocol-75 e progetto-hixie -thewebsocketprotocol-76

Il prototipo può essere trovato presso HTML5 Labs. Inserisco this blog post tutte le informazioni che ho trovato (fino ad ora) e frammenti di codice su come questo può essere fatto usando WCF.

1

Se desideri qualcosa di un po 'più leggero, controlla un server C# che io e un amico abbiamo rilasciato: https://github.com/Olivine-Labs/Alchemy-Websockets

Supporta websocket alla vaniglia e websocket flash. È stato creato per il nostro gioco online con particolare attenzione alla scalabilità e all'efficienza.

10

Il supporto per WebSockets è coming in .NET 4.5. Questi collegamenti contengono anche un esempio che utilizza la classe System.Net.WebSockets.WebSocket.

+2

Dai documenti "le uniche implementazioni pubbliche di client e server WebSockets sono supportate su Windows 8 e Windows Server 2012", ad es. non funzionerà con le versioni precedenti di Windows. –

0

C'è anche l'alchimia. http://olivinelabs.com/Alchemy-Websockets/ che è piuttosto interessante.

+0

e quale non è un client WebSocket – Shaddix

+0

Sì, lo è. C'è una lib di client WebSocket con esso. Guarda di nuovo! – Rushino

+0

In realtà non lo vedo come una lib. C'è una classe [WebSocketClient] (https://github.com/Olivine-Labs/Alchemy-Websockets/blob/master/src/Alchemy/WebSocketClient.cs), però, a destra – Shaddix

4

un'altra scelta: XSockets.Net, ha implementare server e client.

possibile installare il server da:

PM> Install-Package XSockets 

o installare client:

PM> Install-Package XSockets.Client 

versione attuale è: 3.0.4