web-dev-qa-db-fra.com

Serveur Websocket: la fonction onopen sur le socket Web n'est jamais appelée

J'essaie d'implémenter un serveur de socket Web C #, mais cela me donne quelques problèmes. J'exécute un serveur Web (ASP.NET) pour héberger la page avec le javascript et le serveur de socket Web est implémenté comme une application de console C #.

Je suis en mesure de détecter la tentative de connexion du client (chrome exécutant le javascript) et également de récupérer la poignée de main du client. Mais le client ne semble pas accepter la poignée de main que je renvoie (la fonction onopen sur le socket web n'est jamais appelée).

J'ai lu le le protocole Web Socket et je ne vois pas ce que je fais mal. Voici un peu du code du serveur:

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();

J'exécute le serveur Web sur le port 8080 et le serveur de socket Web sur le port 8181, tous deux sur mon hôte local.

J'ai essayé d'envoyer la poignée de main dans différents encodages (ASCII, octets et Hex) mais cela ne semble pas faire de différence. La connexion n'est jamais complètement établie. Le javascript ressemble à ceci:

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');
};

Je suppose que l'erreur réside dans le serveur C # comme chrome envoie les informations comme il se doit, mais comme dit la fonction onopen n'est jamais appelée.

Donc ma question en bref: L'un de vous a-t-il déjà accompli cela - et si oui, comment l'avez-vous fait? Et de cause: voyez-vous des erreurs apparentes dans le code (espérons que ce n'est pas trop demander)

61
Jon List

C'est probablement un problème d'encodage. Voici un serveur C # fonctionnel que j'ai écrit:

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();
    }
}

Et le client correspondant hébergé sur 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>

Cet exemple établit uniquement la poignée de main. Vous devrez modifier le serveur afin de continuer à accepter les données une fois la prise de contact établie.

47
Darin Dimitrov

Veuillez utiliser le codage UTF8 pour envoyer un message texte.

Il existe un serveur websocket open source implémenté par C #, vous pouvez l'utiliser directement.

http://superwebsocket.codeplex.com/

C'est mon projet open source!

24
Kerry Jiang

Le .NET Framework 4.5 introduit la prise en charge des WebSockets dans Windows Communication Foundation. WebSockets est une technologie efficace basée sur des normes qui permet une communication bidirectionnelle sur les ports HTTP standard 80 et 443. L'utilisation des ports HTTP standard permet aux WebSockets de communiquer sur le Web via des intermédiaires. Deux nouvelles liaisons standard ont été ajoutées pour prendre en charge la communication via un transport WebSocket. NetHttpBinding et NetHttpsBinding. Les paramètres spécifiques à WebSockets peuvent être configurés sur l'élément HttpTransportBinding en accédant à la propriété WebSocketSettings.

Je pense qu'il utilise toujours SOAP cependant

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

3
Dave Hillier