2010-11-13 33 views
1

Je semble avoir des difficultés à obtenir une connexion «correcte» entre mon serveur Java et mon client JavaScript. Il semble se connecter correctement, le client envoie son en-tête d'accord, mais c'est aussi loin que possible. Les fonctions onopen ou onmessage ne sont jamais déclenchées du tout.Mon WebSocket ne fonctionne pas comme prévu; le serveur est implémenté en Java et le client est en JavaScript

Voici le code du serveur Java:

import java.net.*; 
import java.io.*; 
public class Server { 
    static DataOutputStream out; 
    public static void main(String[] args) { 
     try { 
      ServerSocket serverSocket = new ServerSocket(8112); 
      System.out.println("Server Started"); 
      while(true) { 
      Socket socket = serverSocket.accept(); 
      System.out.println("A client connected"); 
      out = new DataOutputStream(socket.getOutputStream()); 

      //Send a simple-as-can-be handshake encoded with UTF-8 
      String handshake = "HTTP/1.1 101 Web Socket Protocol Handshake\r" + 
      "Upgrade: WebSocket\r" + 
      "Connection: Upgrade\r" + 
      "WebSocket-Origin: http://localhost\r" + 
      "WebSocket-Location: ws://localhost:8112/\r" + 
      "WebSocket-Protocol: sample\r\n\r\n"; 
      out.write(handshake.getBytes("UTF8")); 
      System.out.println("Handshake sent."); 

      //Send message 'HI!' encoded with UTF-8 
      String message = "HI!"; 
      out.write(0x00); 
      out.write(message.getBytes("UTF8")); 
      out.write(0xff); 
      System.out.println("Message sent!"); 

      //Cleanup 
      socket.close(); 
      out.close(); 
      System.out.println("Everything closed!"); 
     } 
    } catch(Exception e) { 
     System.out.println(e.getMessage()); 
    } 
} 

Et voici le code pour le client:

<html> 
    <head> 
    <meta charset="UTF-8"> 
    <script> 
     function load() { 
     var ssocket = new WebSocket("ws://localhost:8112/"); 
     socket.onopen = function(e) { alert("opened"); } 
     socket.onclose = function(e) { alert("closed"); } 
     socket.onmessage = function(e) { alert(e.data); } 
     } 
    </script> 
    </head> 
    <body onload="load();"> 
    </body> 
</html> 

Pourquoi pas onopen ou onmessage déclencheur? J'ai essayé beaucoup de choses différentes, je n'arrive pas à le faire.

Qu'est-ce que je fais mal?

+0

Quel navigateur utilisez-vous? – SimonJ

+0

Juste remarqué une faute de frappe dans votre extrait de JS ici. "ssocket" devrait être "socket". –

Répondre

5

Il y a un aspect défi-réponse au protocole que vous semblez manquer - le client envoie deux têtes supplémentaires et certaines données aléatoires:

 
GET /demo HTTP/1.1 
Host: example.com 
Connection: Upgrade 
Sec-WebSocket-Key2: 12998 5 Y3 1 .P00 
Sec-WebSocket-Protocol: sample 
Upgrade: WebSocket 
Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5 
Origin: http://example.com 

^n:ds[4U 

et le serveur devrait obtenir une réponse MD5 par:

  • chiffres d'extrait à partir de chaque touche (4146546015, 1299853100)
  • division par nombre d'espaces dans les principaux
  • touches de sérialisation comme nombre entier de 4 octets s, concaténer les données
  • calculer MD5

produire une réponse comme:

 
HTTP/1.1 101 WebSocket Protocol Handshake 
Upgrade: WebSocket 
Connection: Upgrade 
Sec-WebSocket-Origin: http://example.com 
Sec-WebSocket-Location: ws://example.com/demo 
Sec-WebSocket-Protocol: sample 

8jKS'y:G*Co,Wxa- 

Ce processus est conçu pour empêcher les demandes non WebSocket d'être traitées par les serveurs WebSocket - voir la section 1.3 de le WebSocket protocol pour plus de détails.

+0

Cette réponse m'a fait comprendre pourquoi mon client WebSocket (navigateur Web de bureau) ne reçoit pas les réponses de mon android SocketServer. Mais je finis par utiliser [java-websocket.org] (http://java-websocket.org) – Arvin

0

Il y a beaucoup de problèmes possibles ici. HTTP est un protocole de demande-réponse. Vous n'êtes pas censé envoyer d'abord à partir du serveur: vous devez d'abord envoyer une requête au client. Le terminateur de fin de ligne est défini en tant que \ r \ n dans HTTP. Vous devriez créer un nouveau thread par connexion sur le serveur. Vous devez fermer le flux de sortie, pas le socket.

+0

Je suis au courant de toutes ces erreurs "possibles". Avant de venir ici, j'ai essayé d'utiliser '\ r \ n' au lieu de '\ n' ... en fait, j'ai essayé beaucoup de choses différentes, aucune d'entre elles ne faisait de différence. Et le client envoie une poignée de main, dites-vous que je devrais attendre jusqu'à ce que je sache qu'il a fini de l'envoyer avant d'envoyer le serveur? – Ben

+0

Si vous êtes conscient que le terminateur de ligne est \ r \ n, vous devez l'utiliser. – EJP