2010-02-17 16 views
2

Voici mon code:Web Sockets: Browser ne sera pas le message, se plaint à ce sujet ne démarre pas avec 0x00 (octet)

import java.net.*; 
import java.io.*; 
import java.util.*; 
import org.jibble.pircbot.*; 

public class WebSocket 
{ 
    public static int port = 12345; 

    public static ArrayList<WebSocketClient> clients = new ArrayList<WebSocketClient>(); 
    public static ArrayList<Boolean> handshakes = new ArrayList<Boolean>(); 
    public static ArrayList<String> nicknames = new ArrayList<String>(); 
    public static ArrayList<String> channels = new ArrayList<String>(); 
    public static int indexNum; 

    public static void main(String args[]) 
    { 
     try 
     { 
      ServerSocket ss = new ServerSocket(WebSocket.port); 
      WebSocket.console("Created socket on port " + WebSocket.port); 

      while (true) 
      { 
       Socket s = ss.accept(); 
       WebSocket.console("New Client connecting..."); 

       WebSocket.handshakes.add(WebSocket.indexNum,false); 
       WebSocket.nicknames.add(WebSocket.indexNum,""); 
       WebSocket.channels.add(WebSocket.indexNum,""); 
       WebSocketClient p = new WebSocketClient(s,WebSocket.indexNum); 
       Thread t = new Thread(
         p); 
       WebSocket.clients.add(WebSocket.indexNum,p); 
       indexNum++; 
       t.start(); 
      } 
     } 
     catch (Exception e) 
     { 
      WebSocket.console("ERROR - " + e.toString()); 

     } 

    } 

    public static void console(String msg) 
    { 
     Date date = new Date(); 
     System.out.println("[" + date.toString() + "] " + msg); 
    } 



} 


class WebSocketClient implements Runnable 
{ 
    private Socket s; 
    private int iAm; 

    private String socket_res = ""; 
    private String socket_host = ""; 
    private String socket_origin = ""; 

    protected String nick = ""; 
    protected String ircChan = ""; 

    WebSocketClient(Socket socket, int mynum) 
    { 
     s = socket; 
     iAm = mynum; 
    } 

    public void run() 
    { 
     String client = s.getInetAddress().toString(); 
     WebSocket.console("Connection from " + client); 
     IRCclient irc = new IRCclient(iAm); 
     Thread t = new Thread(
       irc 
       ); 
     try 
     { 
      Scanner in = new Scanner(s.getInputStream()); 
      PrintWriter out = new PrintWriter(s.getOutputStream(),true); 

      while (true) 
      { 
       if (! in.hasNextLine()) continue; 
       String input = in.nextLine().trim(); 
       if (input.isEmpty()) continue; 
       // Lets work out what's wrong with our input 
       if (input.length() > 3 && input.charAt(0) == 65533) 
       { 
        input = input.substring(2); 
       } 
       WebSocket.console("< " + input); 
       // Lets work out if they authenticate... 
       if (WebSocket.handshakes.get(iAm) == false) 
       { 
        checkForHandShake(input); 
        continue; 
       } 

       // Lets check for NICK: 
       if (input.length() > 6 && input.substring(0,6).equals("NICK: ")) 
       { 
        nick = input.substring(6); 
        Random generator = new Random(); 
        int rand = generator.nextInt(); 
        WebSocket.console("I am known as " + nick); 
        WebSocket.nicknames.set(iAm, "bo-" + nick + rand); 
       } 

       if (input.length() > 9 && input.substring(0,9).equals("CHANNEL: ")) 
       { 
        ircChan = "bo-" + input.substring(9); 
        WebSocket.console("We will be joining " + ircChan); 
        WebSocket.channels.set(iAm, ircChan); 
       } 

       if (! ircChan.isEmpty() && ! nick.isEmpty() && irc.started == false) 
       { 
        irc.chan = ircChan; 
        irc.nick = WebSocket.nicknames.get(iAm); 
        t.start(); 
        continue; 
       } 
       else 
       { 
        irc.msg(input); 
       } 
      } 
     } 
     catch (Exception e) 
     { 
      WebSocket.console(e.toString()); 
      e.printStackTrace(); 
     } 
     t.stop(); 
     WebSocket.channels.remove(iAm); 
     WebSocket.clients.remove(iAm); 
     WebSocket.handshakes.remove(iAm); 
     WebSocket.nicknames.remove(iAm); 
     WebSocket.console("Closing connection from " + client); 
    } 

    private void checkForHandShake(String input) 
    { 
     // Check for HTML5 Socket 
     getHeaders(input); 

     if (! socket_res.isEmpty() && ! socket_host.isEmpty() && ! socket_origin.isEmpty()) 
     { 
      send("HTTP/1.1 101 Web Socket Protocol Handshake\r\n" + 
           "Upgrade: WebSocket\r\n" + 
           "Connection: Upgrade\r\n" + 
           "WebSocket-Origin: " + socket_origin + "\r\n" + 
           "WebSocket-Location: ws://" + socket_host + "/\r\n\r\n",false); 
      WebSocket.handshakes.set(iAm,true); 
     } 
     return; 
    } 

    private void getHeaders(String input) 
    { 
     if (input.length() >= 8 && input.substring(0,8).equals("Origin: ")) 
     { 
      socket_origin = input.substring(8); 
      return; 
     } 

     if (input.length() >= 6 && input.substring(0,6).equals("Host: ")) 
     { 
      socket_host = input.substring(6); 
      return; 
     } 

     if (input.length() >= 7 && input.substring(0,7).equals("Cookie:")) 
     { 
      socket_res = "."; 
     } 


     /*input = input.substring(4); 
     socket_res = input.substring(0,input.indexOf(" HTTP")); 
     input = input.substring(input.indexOf("Host:") + 6); 
     socket_host = input.substring(0,input.indexOf("\r\n")); 
     input = input.substring(input.indexOf("Origin:") + 8); 
     socket_origin = input.substring(0,input.indexOf("\r\n"));*/ 
     return; 
    } 

    protected void send(String msg, boolean newline) 
    { 
     byte c0 = 0x00; 
     byte c255 = (byte) 0xff; 
     try 
     { 
      PrintWriter out = new PrintWriter(s.getOutputStream(),true); 
      WebSocket.console("> " + msg); 
      if (newline == true) 
       msg = msg + "\n"; 

      out.print(msg + c255); 
      out.flush(); 

     } 
     catch (Exception e) 
     { 
      WebSocket.console(e.toString()); 
     } 
    } 

    protected void send(String msg) 
    { 
     try 
     { 
      WebSocket.console(">> " + msg); 

      byte[] message = msg.getBytes(); 

      byte[] newmsg = new byte[message.length + 2]; 

      newmsg[0] = (byte)0x00; 
      for (int i = 1; i <= message.length; i++) 
      { 
       newmsg[i] = message[i - 1]; 
      } 
      newmsg[message.length + 1] = (byte)0xff; 

      // This prints correctly..., apparently... 
      System.out.println(Arrays.toString(newmsg)); 

      OutputStream socketOutputStream = s.getOutputStream(); 
      socketOutputStream.write(newmsg); 
     } 
     catch (Exception e) 
     { 
      WebSocket.console(e.toString()); 
     } 
    } 

    protected void send(String msg, boolean one, boolean two) 
    { 
     try 
     { 
      WebSocket.console(">> " + msg); 

      byte[] message = msg.getBytes(); 

      byte[] newmsg = new byte[message.length+1]; 

      for (int i = 0; i < message.length; i++) 
      { 
       newmsg[i] = message[i]; 
      } 
      newmsg[message.length] = (byte)0xff; 

      // This prints correctly..., apparently... 
      System.out.println(Arrays.toString(newmsg)); 

      OutputStream socketOutputStream = s.getOutputStream(); 
      socketOutputStream.write(newmsg); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 


} 
class IRCclient implements Runnable 
{ 
    protected String nick; 
    protected String chan; 
    protected int iAm; 

    boolean started = false; 

    IRCUser irc; 

    IRCclient(int me) 
    { 
     iAm = me; 
     irc = new IRCUser(iAm); 
    } 

    public void run() 
    { 
     WebSocket.console("Connecting to IRC..."); 
     started = true; 
     irc.setNick(nick); 
     irc.setVerbose(false); 
     irc.connectToIRC(chan); 
    } 

    void msg(String input) 
    { 
     irc.sendMessage("#" + chan, input); 
    } 


} 

class IRCUser extends PircBot 
{ 
    int iAm; 
    IRCUser(int me) 
    { 
     iAm = me; 
    } 

    public void setNick(String nick) 
    { 
     this.setName(nick); 
    } 

    public void connectToIRC(String chan) 
    { 
     try 
     { 
      this.connect("irc.appliedirc.com"); 
      this.joinChannel("#" + chan); 
     } 
     catch (Exception e) 
     { 
      WebSocket.console(e.toString()); 
     } 

    } 

    public void onMessage(String channel, String sender,String login, String hostname, String message) 
    { 
     // Lets send this message to me 
     WebSocket.clients.get(iAm).send(message); 

    } 

} 

Chaque fois que je tente d'envoyer le message au navigateur (via Web Sockets), il se plaint qu'il ne commence pas par 0x00 (qui est un octet).

Des idées?

Modifier 19/02 - A ajouté le code entier. Je sais que c'est vraiment compliqué et pas très soigné, mais je veux le faire fonctionner en premier.

Passez les deux derniers jours à essayer de réparer.

+0

Quel est le type de "s" que vous utilisez pour "getOutputStream()"? –

+0

ServerSocket ss = nouveau ServerSocket (WebSocket.port); Socket s = ss.accept(); Lorsque j'essaie d'envoyer une chaîne, le Arrays.toString() me donne: [0, 108, 111, 108, -1] - mais le Web Socket se plaint. – giggsey

+0

Pour le client, j'utilise http://github.com/gimite/web-socket-js - C'est un mélange de HTML5 Web Sockets pour les navigateurs qui le supportent (Chrome), et une version Flash pour tout le reste. Mais le Flash émule la socket Web exactement la même chose. L'erreur que le flash fait, comme Chrome ne montre aucune erreur du tout, est: les données doivent commencer par \ x00 \t à WebSocketMain/fatale() \t à WebSocket/onSocketData() – giggsey

Répondre

0

Cela arrive-t-il dès le premier message? ou seulement sur les suivants? Dans ce dernier cas, il y a un problème avec la façon dont vous terminez le premier message ...

+0

Il envoie les en-têtes arrière , et puis c'est sur le premier message (Le client se déconnecte après le msg invalide). – giggsey

+0

Désolé pas capiche. Envoie les en-têtes * en réponse * au 1er message, ou avant? – EJP

+0

Web Sockets fonctionne pour que le client se connecte à ws: //bla.com: 11111. Le client envoie alors des en-têtes (version HTTP, domaine, cookies, etc.). Le serveur les achnolowledges ces, et envoie en arrière (à peu près le même). Ensuite, la "prise de contact" est terminée et la communication normale peut commencer. – giggsey

0

Pourriez-vous vérifier si la prise de contact initiale était terminée avant d'envoyer des images? La poignée de main devrait se terminer par deux lignes vides.

+0

J'ai ajouté tout mon code. Je termine la poignée de main comme ça. (\ r \ n \ r \ n) – giggsey