chrome(客户端)和热点(服务器)之间的Websocket通信(状态行不以CRLF结尾)

时间:2014-09-09 08:19:10

标签: java javascript sockets google-chrome websocket

这就是我所拥有的:

  • 我为我的手机创建了Android应用,我正在使用谷歌播放的应用作为服务器
  • 我打开热点,用户可以通过ip和端口访问我的wifi,例如:192.168.xxx.xxx:8080

他会看到我的网站。我正在使用websockets在javascript和android java之间传递数据。

在Firefox和资源管理器中它工作正常,但在Chrome中它告诉我: “Websocket连接到'ws://192.168.xxx.xxx:9999 /'失败:在websocket握手期间出错:状态行不以CRLF结束”。

我使用了此处的代码:Writing a WebSocket Server  (参见下面的文件“编辑”)。

我也阅读了RFC 6455:https://tools.ietf.org/html/rfc6455,我完全按照那里所写的那样做。

ClientSession

的示例
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class ClientSession {

    private Socket socket;

    public ClientSession(Socket socket) {
        System.out.println("new ClientSessionTest()");
        this.socket = socket;
        initClientListener();
    }

    private void initClientListener() {
        System.out.println("initClientListener()");
        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    BufferedReader socketReader = new BufferedReader(
                            new InputStreamReader(socket.getInputStream()));
                    final PrintWriter socketWriter = new PrintWriter(socket
                            .getOutputStream(), true);
                    String clientKey = null;
                    String responseKey = null;
                    while (true) {
                        String line = socketReader.readLine();
                        if (line == null) {
                            System.out.println("received null from client - closing connection");
                            break;
                        } else if (line.isEmpty()) {
                            System.out.println("empty line");

                            String _01 = "HTTP/1.1 101 Switching Protocols";
                            String _02 = "Upgrade: websocket";
                            String _03 = "Connection: Upgrade";
                            String _04 = "Sec-WebSocket-Accept: " + responseKey;
                            String _05 = "Sec-WebSocket-Protocol: chat";
                            String _06 = "Content-Encoding: identity";

                            System.out.println(_01);
                            System.out.println(_02);
                            System.out.println(_03);
                            System.out.println(_04);
                            System.out.println(_05);
                            System.out.println(_06);
                            System.out.println("");

                            socketWriter.println(_01);
                            socketWriter.println(_02);
                            socketWriter.println(_03);
                            socketWriter.println(_04);
                            socketWriter.println(_05);
                            socketWriter.println(_06);
                            socketWriter.println("");

                            //********************data from client*********************

                            try {
                                byte[] buff = new byte[100];
                                int length = socket.getInputStream().read(buff);

                                byte[] bstr = new byte[length];
                                System.arraycopy(buff, 0, bstr, 0, length);
                                System.out.println(new String(bstr));
                                for (byte b : bstr) {
                                    System.out.print(((int) b) + " ");
                                }
                                System.out.println();
                                System.out.println();
                                String str = new String(decodeFrame(buff),"UTF-8");
                                System.out.println(str);
                            } catch (Exception e) {
                                System.out.println(e.getMessage());

                            //********************************************************

                        }
                        } else if (line.startsWith("Sec-WebSocket-Key:")) {
                            clientKey = line.replace("Sec-WebSocket-Key: ", "");
                            responseKey = ResponseGenerator
                                    .toResponseKey(clientKey);
                        } else {
                            System.out.println("" + line);
                            //socketWriter.println("lala");
                        }

                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
        });
        t.start();
    }

我将字符串_01 =“HTTP / 1.1 101切换协议”更改为字符串_01 =“HTTP / 1.1 101切换协议\ r \ n”; 并且它删除了我在上面写的错误(CRLF),但javascript代码(下面)中的onopen方法没有触发,之后Firefox和Explorer也无法正常工作。

使用Javascript:

<html>
<head>

<script type="text/javascript" >

var websocket;
var url = "ws://localhost:1234";

function init(){
        try{
                websocket = new MozWebSocket(url, "chat");
        }catch(e){
                websocket = new WebSocket(url, "char");
        }

        websocket.onopen = function(evt) { onOpen(evt) };
        websocket.onclose = function(evt) { onClose(evt) };
        websocket.onmessage = function(evt) { onMessage(evt) };
        websocket.onerror = function(evt) { onError(evt) };
}

var count = 0;
function loop(){
        var message = "lala\n";
        websocket.send(message);
        count++;

        setTimeout(loop, 500);
}

function onOpen(event){  
    alert("Socket has been opened!" + ('5' + 3) + ('5' - 3));  

    loop();
}  

function onMessage(evt){  
    alert(evt);  
}  

function onClose(event){  
    alert("socket closed");  
}

function onError(event){
        alert(event.data);
}

window.addEventListener("load", init, false);


</script>

</head>
<body>



</body>
</html>

注意:

我手机上没有互联网连接(没有wifi或3g)。连接仅从用户到我的接入点。

1 个答案:

答案 0 :(得分:1)

我认为这个错误有点误导。似乎每个标题都应以CRLF结束,而不仅仅是第一个(“状态行”)。至少根据test case

String _01 = "HTTP/1.1 101 Switching Protocols\r"; // Added \r here.
String _02 = "Upgrade: websocket\r"; // Added \r here.
String _03 = "Connection: Upgrade\r"; // Added \r here.
String _04 = "Sec-WebSocket-Accept: " + responseKey + "\r"; // Added \r here.
String _05 = "Sec-WebSocket-Protocol: chat\r"; // Added \r here.
String _06 = "Content-Encoding: identity\r"; // Added \r here.

另外,在最后socketWriter.println("") -

中添加另一个\ r \ n
socketWriter.println("\r"); // Added \r here.

也许它会将其标记为响应的结束。

此外,您可以使用Fiddler2(或Wireshark,但它过于冗长)来比较WebSocket实施(根据网络数据)和one that works之间的差异。