0

this is what i have:

  • I created android app for my mobile and i'm using app from google play as a server
  • I open my hotspot and user can access my wifi with ip and port for example: 192.168.xxx.xxx:8080

He will see my website. There i'm using websockets to pass data between javascript and android java.

In Firefox and Explorer it works fine, but in Chrome it tells me: "Websocket connection to 'ws://192.168.xxx.xxx:9999/' failed: Error during websocket handshake: Status line does not end wit CRLF".

I used the code from here: Writing a WebSocket Server (See file below "EDIT").

Also i read RFC 6455: https://www.rfc-editor.org/rfc/rfc6455 and i do exactly as wrote there.

This example of the 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();
    }

I changed the line String _01 = "HTTP/1.1 101 Switching Protocols"; to String _01 = "HTTP/1.1 101 Switching Protocols\r\n"; and its remove the error (CRLF) i wrote above but the onopen method from the javascript code (below) is not firing and after that also Firefox and Explorer are not working.

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>

Notice:

I dont have an internet connection (no wifi or 3g) in my mobile. the connection is only from the user to my access point.

Community
  • 1
  • 1
erani_246
  • 225
  • 4
  • 16
  • Ok, so i added \r to the first line "String _01 = "HTTP/1.1 101 Switching Protocols";", now its "String _01 = "HTTP/1.1 101 Switching Protocols\r";". Now the error ("Status line does not end with CRLF") is gone but still the "websocket.onopen" method isn't trigered. – erani_246 Sep 10 '14 at 05:56
  • You ended the response after the status line (this is the purpose of CRLF does), instead of after the headers, so the browser did not even know you were trying to initiate a WebSocket connection, so it did not show any error. – PhistucK Sep 13 '14 at 07:01
  • Correction - "instead of after the headers" should be "instead of after each of the headers". The browser effectively saw a single line `Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: xxxxx Sec-WebSocket-Protocol: chat Content-Encoding: identity` which is clearly not a WebSocket handshake of any kind. It is very surprising that Internet Explorer and Firefox are fine with this. – PhistucK Sep 13 '14 at 07:10
  • You followed the WebSocket RFC, but the handshake itself follows the HTTP protocol (as it is an HTTP request and an HTTP response). Your part is the response, which is defined here - https://tools.ietf.org/html/rfc2616#section-6 - and you can see that every header (including the status line) must end with CRLF. – PhistucK Sep 13 '14 at 07:19

1 Answers1

2

I think the error is a bit misleading. Every header should end with CRLF and not only the first one (the 'status line'), it seems. At least according to the 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.

Also, add another \r in the last socketWriter.println("") -

socketWriter.println("\r"); // Added \r here.

Perhaps it will mark it as the end of the response.

Also, you can use Fiddler2 (or Wireshark, but it is too verbose) to compare the differences between your WebSocket implementation (in terms of the network data) and one that works.

PhistucK
  • 2,466
  • 1
  • 26
  • 28
  • Ok, i added \r to socketWriter.println("\r") at the end of the response and now its work perfectly! thanks a lot PhistucK!! Great answer! – erani_246 Sep 13 '14 at 19:11
  • I am glad it worked. Only there? What about for every header? – PhistucK Sep 13 '14 at 20:11
  • Thanks again!! Only: String _01 = "HTTP/1.1 101 Switching Protocols\r" and socketWriter.println("\r"); – erani_246 Sep 14 '14 at 06:30
  • 1
    I advise you to try adding them to all of the headers, as you may have problems in the future, because I believe it is not conformant. It would be too bad for the code to break again if they make the parsing stricter. – PhistucK Sep 14 '14 at 06:51