2014-12-06 4 views
2

Я хотел бы иметь возможность использовать браузер в качестве редактора для sms на моем устройстве Android (что-то вроде https://www.mysms.com). поэтому я начал писать приложение для Android, которое выступает в качестве сервера сокетов и использует браузер как клиент (например, http://www.websocket.org/echo.html). я смог связаться с моим клиентом и получить от него сообщения, но у меня возникают проблемы с рукопожатием WebSocket (Sec-WebSocket-Key и т. д.).создать рукопожатие с использованием android в качестве сервера и браузера как клиента

EDIT:

я следовал этому учебнику, чтобы написать мой андроид сервер: http://android-er.blogspot.co.at/2014/02/android-sercerclient-example-server.html

, когда я пытался достигнуть этот сервер от http://www.websocket.org/echo.html я получил это Js ошибки: Ошибки при WebSocket рукопожатия: Invalid строки состояния

РЕДАКТИРОВАТЬ:

так я добавил заголовок с закодированным ключом для втор-WebSocket-Accept: линия

// get the key from the input 
InputStream inputStream = hostThreadSocket.getInputStream(); 
      String line = ""; 
      BufferedReader reader = null; 
      try { 
       reader = new BufferedReader(new InputStreamReader(inputStream)); 
       while ((line = reader.readLine()) != null) { 
        if(line.contains("Sec-WebSocket-Key:")){ // stop then the line containing the key is found 
         break; 
        } 
       } 

      } catch (IOException e) { 
      } 
String key = line.replace("Sec-WebSocket-Key:", ""); 

и кодировать результат с следующим способом:

static String encodeString(String input) { 

    MessageDigest digest = null; 
    try { 
     digest = MessageDigest.getInstance("SHA-1"); 
     byte[] inputBytes = input.getBytes(); 
     byte[] hashBytes = digest.digest(inputBytes); 
     return Base64.encodeToString(hashBytes, Base64.DEFAULT); 
    } catch (NoSuchAlgorithmException e) { 
     e.printStackTrace(); 
    } 
    return ""; 
} 

и передать заголовок как следующие:

String key = line.replace("Sec-WebSocket-Key:", ""); 
      key = key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; 
      key = encodeString(key).replace("\n", "");; 

      String header = "HTTP/1.1 101 Switching Protocols\r\n" + 
        "Upgrade: websocket \r\n" + 
        "Connection: Upgrade \r\n" + 
        "Sec-WebSocket-Accept: " + key + "\r\n"+ 
        "Sec-WebSocket-Protocol: chat\r\n\r\n" + msgReply; 
      printStream.print(header); 
      printStream.close(); 

заголовок ответа теперь выглядит так:

Connection:Upgrade\r\n 
Sec-WebSocket-Accept:/Qg4DR68UCCo9VKy4vbDgswCU8Y=\r\n 
Upgrade:websocket\r\n 

но все же я получаю ошибку: failed: Ошибка во время рукопожатия WebSocket: неверное значение заголовка «Sec-WebSocket-Accept»

+0

Что проблема с рукопожатия? Можете ли вы привести примеры HTTP-запроса и ответа, который вы получаете? – vtortola

+0

Я обновил свой вопрос с более подробной информацией. – richard

ответ

2

я наконец мог сделать WebSocket рукопожатие. я не знаю, какие именно изменения которые привнесли меня к успеху, но это рабочий код:

InputStream inputStream = hostThreadSocket.getInputStream(); 
      String line = ""; 
      BufferedReader reader = null; 
      try { 
       reader = new BufferedReader(new InputStreamReader(inputStream)); 
       while ((line = reader.readLine()) != null) { 
        if (line.contains("Sec-WebSocket-Key: ")) { // check if its the header-line containing the websocket key 
         break; 
        } 
       } 
      } catch (IOException e) { 
       Log.e(TAG_TEST, e.getMessage(), e); 
      } 

      Matcher matcher = pattern.matcher(line); // with pattern "Sec-WebSocket-Key:[ ]*([^\r^\n]*)" to parse the key out of the line 
      boolean matches = matcher.matches(); 
      String key = matcher.group(1); 
      key = key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // adding the "magic string" 
      key = encodeString(key); 

      String header = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" +      
        "Upgrade: websocket\r\n" + 
        "Connection: Upgrade\r\n" + 
        "Sec-WebSocket-Accept:" + key + "\r\n\r\n"; 
      printStream.print(header); 

и это метод, я, который кодирует ключевой

static String encodeString(String input) { 
    MessageDigest digest = null; 
    try { 
     digest = MessageDigest.getInstance("SHA-1"); 
     byte[] inputBytes = input.getBytes(); 
     byte[] hashBytes = digest.digest(inputBytes); 
     return Base64.encodeToString(hashBytes, Base64.NO_WRAP); 
    } catch (NoSuchAlgorithmException e) { 
     Log.e(TAG_TEST, e.getMessage(), e); 
    } 
    return ""; 
} 
+0

Большое спасибо за предоставление вашего решения. Помог мне много. – charliebeckwith