Веб-сокеты: браузер не получает сообщение, жалуется на то, что оно не начинается с 0x00 (байт) - PullRequest
2 голосов
/ 17 февраля 2010

Вот мой код:

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

    }

}

Всякий раз, когда я пытаюсь отправить сообщение в браузер (через веб-сокеты), он жалуется, что не начинается с 0x00 (что является байтом).

Есть идеи?

Редактировать 19/02 - Добавлен весь код. Я знаю, что это действительно грязно и не аккуратно, но я хочу, чтобы это сначала заработало.

Проведите последние два дня, пытаясь исправить.

Ответы [ 2 ]

0 голосов
/ 19 февраля 2010

Не могли бы вы проверить, было ли начальное рукопожатие завершено перед отправкой кадров? Рукопожатие должно заканчиваться двумя пустыми строками.

0 голосов
/ 18 февраля 2010

Это происходит в самом первом сообщении? или только на последующих? Если последнее, что-то не так с тем, как вы заканчиваете первое сообщение ...

...