2010-02-06 19 views
60

Próbuję zaimplementować serwer gniazd C#, ale daje mi to kilka kłopotów. Używam serwera WWW (ASP.NET) do hostowania strony z javascript, a serwer gniazda sieciowego jest zaimplementowany jako aplikacja konsoli C#.Serwer sieci Web: funkcja onopen na gnieździe sieciowym nigdy nie jest nazywana

Jestem w stanie wykryć próbę połączenia od klienta (chrome z obsługą javascript), a także pobrać handshake od klienta. Ale klient nie wydaje się akceptować uścisku dłoni, który wysyłam (funkcja onopen w gnieździe internetowym nigdy nie jest wywoływana).

Czytałem The Web Socket protocol i nie widzę, co robię źle. Herezje trochę kodu serwera:

Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); 
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8181); 
listener.Bind(ep); 
listener.Listen(100); 
Console.WriteLine("Wainting for connection..."); 
Socket socketForClient = listener.Accept(); 
if (socketForClient.Connected) 
{ 
    Console.WriteLine("Client connected"); 
    NetworkStream networkStream = new NetworkStream(socketForClient); 
    System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(networkStream); 
    System.IO.StreamReader streamReader = new System.IO.StreamReader(networkStream); 

    //read handshake from client: 
    Console.WriteLine("HANDSHAKING..."); 
    char[] shake = new char[255]; 
    streamReader.Read(shake, 0, 255); 

    string handshake = 
     "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" + 
     "Upgrade: WebSocket\r\n" + 
     "Connection: Upgrade\r\n" + 
     "WebSocket-Origin: http://localhost:8080\r\n" + 
     "WebSocket-Location: ws://localhost:8181\r\n" + 
     "\r\n"; 

    streamWriter.Write(handshake); 
    streamWriter.Flush(); 

biegnę do serwera WWW na porcie 8080 i serwerem websocket na porcie 8181, zarówno na moim localhost.

Próbowałem wysyłać uścisk dłoni w różnych kodowań (ASCII, bajtów i Hex), ale to nie wydaje się mieć znaczenia. Połączenie nigdy nie jest w pełni ustalone. javascript wygląda następująco:

var ws; 
var host = 'ws://localhost:8181'; 
debug("Connecting to " + host + " ..."); 
try { 
ws = new WebSocket(host); 
} catch (err) { 
debug(err, 'error'); 
} 
ws.onopen = function() { 
debug("connected...", 'success'); 
}; 
ws.onclose = function() { 
debug("Socket closed!", 'error'); 
}; 
ws.onmessage = function (evt) { 
debug('response: ' + evt, 'response'); 
}; 

Zgaduję, że błąd tkwi w serwerze C# jak chrom wysyła informacje jak powinien, ale jako że funkcja onopen nigdy nie jest wywoływana.

Moje pytanie w skrócie: Czy ktokolwiek z was kiedykolwiek to osiągnął - a jeśli tak, jak to zrobiłeś? I przyczyny: Czy widzisz jakieś oczywiste błędy w kodzie (mam nadzieję, że nie ma zbyt wiele do zapytania)

+1

może chcesz używać Fleck, dostępny na Nuget: http://nuget.org/packages/Fleck/ –

Odpowiedz

47

Prawdopodobnie jest to problem z kodowaniem. Oto pracuje serwer C# pisałem:

class Program 
{ 
    static void Main(string[] args) 
    { 
     var listener = new TcpListener(IPAddress.Loopback, 8181); 
     listener.Start(); 
     using (var client = listener.AcceptTcpClient()) 
     using (var stream = client.GetStream()) 
     using (var reader = new StreamReader(stream)) 
     using (var writer = new StreamWriter(stream)) 
     { 
      writer.WriteLine("HTTP/1.1 101 Web Socket Protocol Handshake"); 
      writer.WriteLine("Upgrade: WebSocket"); 
      writer.WriteLine("Connection: Upgrade"); 
      writer.WriteLine("WebSocket-Origin: http://localhost:8080"); 
      writer.WriteLine("WebSocket-Location: ws://localhost:8181/websession"); 
      writer.WriteLine(""); 
     } 
     listener.Stop(); 
    } 
} 

a odpowiadający klient obsługiwany na localhost:8080:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
    <script type="text/javascript"> 
     var socket = new WebSocket('ws://localhost:8181/websession'); 
     socket.onopen = function() { 
     alert('handshake successfully established. May send data now...'); 
     }; 
     socket.onclose = function() { 
     alert('connection closed'); 
     }; 
    </script> 
    </head> 
    <body> 
    </body> 
</html> 

Ten przykład ustanawia tylko uścisk dłoni. Będziesz musiał zmodyfikować serwer, aby kontynuować przyjmowanie danych po ustanowieniu uścisku dłoni.

+1

Dzięki! Okazało się, że to część uścisku dłoni w WebSocket-Location sprawiała mi kłopoty. Najwyraźniej nie może to być po prostu "ws: // localhost: 8181". Po zmianie na "ws: // localhost: 8181/something" i zmianie hosta w javascript na to samo - zadziałało. –

+0

Dzięki za wpis. Próbowałem tego w Chrome + statyczny plik html i musiałem zmienić jego pochodzenie, aby uniemożliwić natychmiastowe odłączenie przeglądarki: writer.WriteLine ("WebSocket-Origin: file: //"); –

+0

@Darin Twój kod działa poprawnie. Nie działało, gdy usunąłem to "używanie" i zadeklarowałem, że "pisarz" jak zwykle. Rzecz w tym, że pisarz nie odpisał do klienta. Czy możesz to wyjaśnić? – prabhakaran

24

Proszę użyć kodowania UTF8, aby wysłać wiadomość tekstową.

Istnieje serwer websocket open source, który jest zaimplementowany przez C#, można go użyć bezpośrednio.

http://superwebsocket.codeplex.com/

To mój projekt open source!

+2

Teraz SuperWebSocket zawiera również implementację klienta WebSocket! –

3

.NET Framework 4.5 wprowadza obsługę WebSockets w Windows Communication Foundation. WebSockets jest wydajną, opartą na standardach technologią , która umożliwia komunikację dwukierunkową przez standardowe porty HTTP 80 i 443 o numerze . Korzystanie ze standardowych portów HTTP umożliwia komunikację w Internecie przez pośredników. Dwa nowe standardowe wiązania zostały dodane w celu obsługi komunikacji za pośrednictwem transportu WebSocket o numerze . NetHttpBinding i NetHttpsBinding. Ustawienia specyficzne dla WebSockets można skonfigurować na elemencie HttpTransportBinding , uzyskując dostęp do właściwości WebSocketSettings .

myślę, że nadal używa SOAP chociaż

http://msdn.microsoft.com/en-us/library/hh674271(v=vs.110).aspx