2010-04-29 28 views
1

Après avoir joué avec cela pendant des heures, je ne trouve tout simplement pas de solution. Je travaille sur un serveur WebSocket en utilisant "node.js" pour un jeu en ligne sur toile que je développe. Mon jeu peut très bien se connecter au serveur, il accepte la poignée de main et peut même envoyer des messages au serveur. Cependant, lorsque le serveur répond au client, le client n'obtient pas le message. Pas d'erreur, rien, ça se repose tranquillement. J'ai déchiré mon code, essayant tout ce que je pouvais penser pour résoudre ce problème, mais hélas, rien.Pourquoi l'événement WebSocket.onmessage ne se déclenche-t-il pas?

Voici une copie dépouillée de mon code serveur. Comme je l'ai déjà dit, la poignée de main fonctionne bien, le serveur reçoit bien les données, mais n'envoie pas les données au client.

var sys = require('sys'), 
net = require('net'); 
var server = net.createServer(function (stream) { 
    stream.setEncoding('utf8'); 
    var shaken = 0; 
    stream.addListener('connect', function() { 
     sys.puts("New connection from: "+stream.remoteAddress); 
    }); 
    stream.addListener('data', function (data) { 
     if (!shaken) { 
      sys.puts("Handshaking..."); 
      //Send handshake: 
      stream.write(
      "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"+ 
      "Upgrade: WebSocket\r\n"+ 
      "Connection: Upgrade\r\n"+ 
      "WebSocket-Origin: http://192.168.1.113\r\n"+ 
      "WebSocket-Location: ws://192.168.1.71:7070/\r\n\r\n"); 
      shaken=1; 
      sys.puts("Handshaking complete."); 
     } 
     else { 
      //Message received, respond with 'testMessage' 
      var d = "testMessage"; 
      var m = '\u0000' + d + '\uffff'; 
      sys.puts("Sending '"+m+"' to client"); 
      var result = stream.write(m, "utf8"); 
    /* 
      Result is equal to true, meaning that it pushed the data out. 
      Why isn't the client seeing it?!? 
      */ 
     } 
    }); 
    stream.addListener('end', function() { 
     sys.puts("Connection closed!"); 
    stream.end(); 
    }); 
}); 
server.listen(7070); 
sys.puts("Server Started!"); 

Voici mon code côté client. Il utilise des WebSockets natives Chrome.

socket = new WebSocket("ws://192.168.1.71:7070"); 
socket.onopen = function(evt) { 
    socket.send("blah"); 
    alert("Connected!"); 
}; 
socket.onmessage = function(evt) { 
    alert(evt.data); 
}; 
+0

Quel est le côté client? Constructions Chrome native-WebSocket? Flashback fallback? – bobince

+1

Je l'ai édité et ajouté le code du côté client. Désolé, je suis vraiment fatigué heh. – SumWon

Répondre

4
var m = '\u0000' + d + '\uffff'; 
var result = stream.write(m, "utf8"); 

Ah, qui ne semble pas tout à fait raison. Il doit s'agir d'un octet zéro, suivi d'une chaîne codée en UTF-8, suivie d'un octet 0xFF.

\uFFFF ne code pas en UTF-8 à un octet 0xFF: vous obtenez 0xC3 0xBF. En fait, aucun caractère ne produira jamais un codage 0xFF en UTF-8: c'est pourquoi il a été choisi comme terminateur dans WebSocket.

Je ne suis pas familier avec Node.js, mais je suppose que vous auriez besoin de dire quelque chose comme:

stream.write('\u0000'+d, 'utf-8'); 
stream.write('\xFF', 'binary'); 

ou manuellement encode UTF-8 et envoyer en binaire. Le protocole de transfert est également discutable, même si je suppose que c'est un premier brouillon simple qui fonctionne probablement pour vous en ce moment. Vous comptez sur le premier paquet étant l'en-tête de poignée de main entier et rien d'autre, alors le deuxième paquet étant les données de charge utile. Ce n'est pas du tout garanti. Vous voudrez probablement recueillir data dans un tampon jusqu'à ce que vous voyiez le marqueur 0x0D 0x0A 0x0D 0x0A pour la fin des en-têtes, puis vérifier le contenu de l'en-tête et éventuellement retourner le 101, puis continuer à partir des données après ce marqueur.

+0

Oh wow, une solution si simple! Merci beaucoup! Je me suis arraché les cheveux pendant des heures pour essayer de résoudre ça! Comme vous l'avez dit, la poignée de main n'est qu'un premier brouillon temporaire, aussi simple que possible, et j'en ferai un meilleur plus tard. Encore une fois, merci un million! – SumWon