2016-03-26 4 views
0

Ich habe auf einem Server (in Java) und Client in JavaScript mit Websockets gearbeitet, und alles funktioniert nur in Android finden, aber wenn ich es auf dem iPhone getestet, wird die JavaScript-Seite aufgehängt auf jedem websocket.send-Methode.Javascript Websocket OnOpen nicht auf IOS

Auf Android läuft die gameButton-Funktion durch und gibt "Send!" Aus. auf der Seite, und der Server empfängt die Nachricht. Auf IOS gibt die gameButton-Funktion etwas wie "Input: u" aus, hängt aber anscheinend an connection.send und gibt "Sent!" Nicht aus, und der Server empfängt die Nachricht nicht. Die OnOpen-Funktion wird nie auf dem iPhone, sondern auf Android aufgerufen. Irgendwelche Ideen? Lassen Sie mich wissen, wenn Sie etwas vom Servercode sehen müssen.

Entschuldigung für den langen Code!

Javascript für den Kunden:

<!DOCTYPE html> 

<html> 

<head> 
    <title>Echo Test</title> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width"> 
</head> 

<body onload="pageLoad()" style="background:black; color:cyan"> 
    <div id="joinform"> 
     <input type="text" id="username" value="Username..."></input> 
     <button id="joinbutton" onclick="joinSubmit()">Join!</button></div> 
    <div id="gamecontrols"> 
     <button onclick="gameButton('u')" id="upbutton"> UP </button> 
     <button onclick="gameButton('d')" id="downbutton">DOWN</button></div> 
    <div id="leftDiv" style="float:left; width=10%; height=300px"><canvas id="leftCanvas" style="border:2px solid cyan"></canvas> </div> 
    <div id="rightDiv" style="float:left; width=10%; height=300px"><canvas id="rightCanvas" style="border:2px solid cyan"></canvas> </div> 
    <div id="statusdiv"> </div> 
    <div id="messages"></div> 
</body> 
<script type="text/javascript"> 
var connection = new WebSocket('ws://174.51.xxx.xx:9091'); 
var messages = document.getElementById("messages"); 
var username = document.getElementById("username"); 
var joinbutton = document.getElementById("joinbutton"); 
var game = document.getElementById("gamecontrols"); 
var joinform = document.getElementById("joinform"); 
var state = 0; 

var leftCanvas = document.getElementById('leftCanvas') 
var rightCanvas = document.getElementById('rightCanvas'); 
var statusdiv = document.getElementById('statusdiv') 
var startx = 0 
var starty = 0; 
var distx = 0; 
var disty = 0; 


// When the connection is open, send some data to the server 
connection.onopen = function(e) { 
    writeResponse('Open!'); 
    connection.send('TEST'); 
} 

// Log errors 
connection.onerror = function(error) { 
    writeResponse('Error: ' + error); 
} 

connection.onclose = function(e) { 
    writeResponse("Disconnected: " + e.data); 
} 

// Log messages from the server 
connection.onmessage = function(e) { 
    writeResponse('Server: ' + e.data); 
} 

function pageLoad() { 
    game.style.visibility = "hidden"; 
} 

function writeResponse(text) { 
    messages.innerHTML += "<br/>" + text; 
} 

function joinSubmit() { 
    game.style.visibility = "visible"; 
    //connection.send(username.value); 
    writeResponse("Username sent to server."); 
    joinform.remove(); 

    leftCanvas.addEventListener('touchstart', function(e) { 
     var touchobj = e.changedTouches[0] // reference first touch point (ie: first finger) 
     startx = parseInt(touchobj.clientX) // get x position of touch point relative to left edge of browser 
     starty = parseInt(touchobj.clientY) 
     statusdiv.innerHTML = 'Status: touchstart<br> ClientX: ' + startx + 'px' 

     drawJoystick(startx, starty); 
     e.preventDefault() 
    }, false) 

    leftCanvas.addEventListener('touchmove', function(e) { 
     e.preventDefault() 
     var touchobj = e.changedTouches[0] // reference first touch point for this event 
     var distx = parseInt(touchobj.clientX) - startx 
     var disty = parseInt(touchobj.clientY) - starty 
     statusdiv.innerHTML = 'Status: touchmove<br> Horizontal distance traveled: ' + distx + 'px<br> Vertical distance traveled: ' + disty + 'px' + 
      '<br>Dist: ' + Math.sqrt((startx - (distx + startx)) * (startx - (distx + startx)) + (starty - (disty + starty)) * (starty - (disty + 
       starty))); 
     //connection.send("L=" + distx + "=" + disty); 
     connection.send("A=" + Math.floor(angleBetween2Lines(startx, starty, startx + distx, starty + disty) + 90) * -1); 
     connection.send("B=" + distx + "=" + disty); 

    }, false) 

    leftCanvas.addEventListener('touchend', function(e) { 
     var touchobj = e.changedTouches[0] // reference first touch point for this event 
     statusdiv.innerHTML = 'Status: touchend<br> Resting x coordinate: ' + touchobj.clientX + 'px' 
     e.preventDefault() 
    }, false) 

} 

function gameButton(ctrl) { 
    writeResponse("Control: " + ctrl); 
    connection.send(ctrl); 
    writeResponse("Sent!"); 
} 

function find_angle(x1, y1, x2, y2) { 
    var AB = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)); 
    var BC = Math.sqrt(Math.pow(x2 - (x1 - 10), 2) + Math.pow(y2 - y1, 2)); 
    var AC = Math.sqrt(Math.pow((x1 - 10) - x1, 2) + Math.pow(y1 - y1, 2)); 
    return Math.acos((BC * BC + AB * AB - AC * AC)/(2 * BC * AB)) * (180/Math.PI); 
} 

function angleBetween2Lines(x1, y1, x2, y2) { 
    var angle1 = Math.atan2(y1 - y1, 
     x1 - (x1 + 100)); 
    var angle2 = Math.atan2(y1 - y2, 
     x1 - x2); 
    return angle1 - angle2 * (180/Math.PI); 
} 
</script> 

</html> 

EDIT: Getestet habe ich den genauen Code auf dieser Seite http://websocket.org/echo.html und es scheint sowohl auf Android und iOS zu funktionieren, so dass ich nicht wirklich sicher, was meine verursacht Websocket-Implementierung, um auf iOS zu brechen ... Irgendwelche Ideen, was die connection.send() -Funktion veranlassen würde, einzufrieren und den Rest der Javascript-Methode zu blockieren, um zu laufen?

UPDATE: Ich habe meinen Servercode auf die kürzestmögliche Form reduziert, und es funktioniert immer noch auf Android, aber nicht auf jedem iPhone, das ich ausprobiert habe. Auch über die Javascript-Code nicht den Aufruf der "connection.onopen" Funktion in iPhone, aber es auf Android wird genannt ...

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.io.UnsupportedEncodingException; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 
import java.util.Base64; 

import javax.xml.bind.DatatypeConverter; 

public class DateServer { 

    static String[] headers = new String[10]; 
    static String[] bodies = new String[10]; 

    public static void main(String[] args) throws IOException, NoSuchAlgorithmException { 

     ServerSocket listener = new ServerSocket(9091); 
     try { 
      while (true) { 
       Socket socket = listener.accept(); 
       System.out.println("Accepted"); 
       BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
       String msg; 

       while ((msg = input.readLine()) != null) { 
        if (msg.length() == 0) 
         break; 

        parseHeaders(msg); 

       } 

       String httpResponse = returnHeader(); 

       try { 
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 

        out.println(httpResponse + "\n"); 
        out.flush(); 
        System.out.println("Sent HTTP Response"); 
       } finally { 

       } 
      } 
     } 
     finally { 
      listener.close(); 
     } 
    } 

    public static void parseHeaders(String in) { 
     System.out.println(in); 
     String[] thisLine = in.split(": "); 

     if (thisLine[0].equals("Host")) { 
      bodies[0] = thisLine[1]; 
     } 
     else if (thisLine[0].equals("Upgrade")) { 
      bodies[1] = thisLine[1]; 
     } 
     else if (thisLine[0].equals("Connection")) { 
      bodies[2] = thisLine[1]; 
     } 
     else if (thisLine[0].equals("Sec-WebSocket-Key")) { 
      bodies[3] = thisLine[1]; 
     } 
     else if (thisLine[0].equals("Sec-WebSocket-Version")) { 
      bodies [4] = thisLine[1]; 
     } 
    } 

    public static String returnHeader() throws NoSuchAlgorithmException, UnsupportedEncodingException { 
     String head = "HTTP/1.1 101 Web Socket Protocol Handshake\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "; 

     String key = bodies[3]; 
     String encoded = WebSocketAccept(key); 

     String httpResponse = head.concat(encoded); 
     httpResponse.concat("\r\n\r\n"); // is concat not working?? 
     return httpResponse; 
    } 

    private static String WebSocketAccept(String message) throws NoSuchAlgorithmException, UnsupportedEncodingException { 
     message = message.concat("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); 
     MessageDigest digest = MessageDigest.getInstance("SHA-1"); 
     byte[] hashedBytes = digest.digest(message.getBytes("UTF-8")); 
     return convertByteArrayToHexString(hashedBytes); 
    } 

    private static String convertByteArrayToHexString(byte[] arrayBytes) { 
     StringBuffer stringBuffer = new StringBuffer(); 
     for (int i = 0; i < arrayBytes.length; i++) { 
      stringBuffer.append(Integer.toString((arrayBytes[i] & 0xff) + 0x100, 16).substring(1)); 
     } 
     return convertHexToBase64(stringBuffer.toString()); 
    } 

    private static String convertHexToBase64(String hex) { 
     byte[] hexToBytes = DatatypeConverter.parseHexBinary(hex); 
     String base64 = Base64.getEncoder().encodeToString(hexToBytes); 
     System.out.println(base64); 
     return base64; 
    } 
} 

Hier sind die Header der Server von Android vs iPhone erhält:

Android:

GET/HTTP/1.1 
Host: 174.51.xxx.xx:9091 
Connection: Upgrade 
Pragma: no-cache 
Cache-Control: no-cache 
Upgrade: websocket 
Origin: http://server.site88.net 
Sec-WebSocket-Version: 13 
User-Agent: Mozilla/5.0 (Linux; Android 5.0; SM-G900V Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.91 Mobile Safari/537.36 
Accept-Encoding: gzip, deflate, sdch 
Accept-Language: en-US,en;q=0.8 
Sec-WebSocket-Key: IKTSyKHA8zclXsm2hFzm5Q== 
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits 

iPhone:

GET/HTTP/1.1 
Upgrade: websocket 
Connection: Upgrade 
Host: 174.51.xxx.xx:9091 
Origin: http://server.site88.net 
Pragma: no-cache 
Cache-Control: no-cache 
Sec-WebSocket-Key: Sq0xOYhkomBmiyMbGwp/kQ== 
Sec-WebSocket-Version: 13 
Sec-WebSocket-Extensions: x-webkit-deflate-frame 
User-Agent: Mozilla/5.0 (iPhone; CPU iPhone OS 9_2_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13D15 Safari/601.1 

Antwort

0

ich es herausgefunden. Als ich die Header zum Zurücksenden an den Browser vom Server her erstellte, verwendete ich "httpResponse.concat (" \ r \ n \ r \ n ")" um Zeilenumbrüche am Ende der Header hinzuzufügen, was einfach nicht funktionierte . Ändern Sie es in "httpResponse = httpResponse +" \ r \ n \ r \ n ";" funktioniert.