2015-03-20 19 views
5

Mi piacerebbe chiedere come creare un socket PHP che possa ricevere richieste da telefono Android in tempo reale? Per ora, ho fatto questa parte del codice e sono riuscito a testarlo usando telnet. Tuttavia, quando il telefono Android tenta di connettersi, non può ricevere o inviare nulla al server.PHP Socket con android

if (!defined('SOCKET_ADDRESS')) { 
    define('SOCKET_ADDRESS', '192.168.1.4'); 
} 

if (!defined('SOCKET_PORT')) { 
    define('SOCKET_PORT', '5888'); 
} 

if (!defined('MAX_CLIENTS')) { 
    define('MAX_CLIENTS', '10'); 
} 
set_time_limit(0); 

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); 
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1); 
socket_bind($socket, SOCKET_ADDRESS, SOCKET_PORT) or die('Could not bind to address ' . SOCKET_ADDRESS . ' on port ' . SOCKET_PORT . "!\n"); 
socket_listen($socket, MAX_CLIENTS) or die("Could not setup socket listener!\n"); 

// setup read socket array 
$read = array(); 

// client array w/ default initial socket 
$clients = array('0' => array('socket' => $socket)); 

// force debug at first run.. 
$debug = true; 
$time = time(); 
printf('Time: %d%s', $time, "\n"); 
$status = true; 
while ($status) { 

    if (time() - $time >= 10) { 
     $time = time(); 
     printf('Time: %d%s', $time, "\n"); 
     $debug = true; 
    } 
    if ($debug === true) { 
     printf('Debug: %s%s', $debug, "\n"); 
    } 
    // $read[0] = $socket; 
    if ($debug) { 
     var_dump($read); 
    } 

    // Handle clients 
    for ($i = 0; $i < count($clients); $i++) { 
     if (isset($clients[$i]['socket'])) { 
      if ($debug === true) { 
       printf('Setting socket %d to client %d%s', $i, $i, "\n"); 
      } 
      $read[$i] = $clients[$i]['socket']; 
     } 
    } 
    if ($debug) { 
     var_dump($read); 
    } 
    // Any changed sockets? 
    // $write and $except are only placeholders 
    $changed_sockets = socket_select($read, $write = NULL, $except = NULL, 0); 
    if ($debug === true) { 
     printf('Changed sockets: %d%s', $changed_sockets, "\n"); 
    } 
    // Handle new connections 
    if (in_array($socket, $read)) { 
     for ($i = 0; $i < MAX_CLIENTS; $i++) { 
      if (!isset($clients[$i])) { 
       $clients[$i]['socket'] = socket_accept($socket); 
       socket_getpeername($clients[$i]['socket'], $ip); 
       $clients[$i]['ip'] = $ip; 
       printf('Accepting connection into client %d from %s%s', $i, $ip, "\n"); 
       break; 
      } 
      // } elseif($i == MAX_CLIENTS - 1) { 
      // echo 'Too many clients connected!', "\n"; 
      // } 
      if ($changed_sockets < 1) { 
       continue; 
      } 
     } 
    } 
    if ($debug) { 
     var_dump($clients); 
    } 

    for ($i = 0; $i < count($clients); $i++) { 
     $client = $clients[$i]; 
     // Has our client socket seen any changes? 
     if (in_array($client['socket'], $read)) { 
      printf('Client %d has changed! Reading...%s', $i, "\n"); 
      $data = socket_read($client['socket'], 1024); 
      if ($data === false) { 
       $error = socket_strerror(socket_last_error()); 
       printf('An error occured...%s%s', $error, "\n"); 
      } 
      printf("Read raw data %s from client %i%s", $data, $i, "\n"); 
      if ($data === null) { 
       // disconnected 
       unset($clients[$i]); 
      } 

      $data = trim($data); 
      if ($data == 'Q') { 
       printf('Received exit command from client%s', "\n"); 
       socket_close($clients[$i]['socket']); 
       $status = false; 
      } elseif ($data) { 
       // Strip whitespace 
       printf('Received data: %s from client %d%s', $data, $i, "\n"); 
       $output = sprintf('%s%s%s', $data, "\n", chr(0)); 
       socket_write($client['socket'], $output); 
      } 
     } 
    } 

    // reset debug 
    $debug = false; 
} 

socket_close($socket); 

risposta

2

Aggiungere questa libreria in build.gradle.

compile "org.java-websocket:Java-WebSocket:1.3.0" 

per collegare:

private void connectWebSocket() { 
    URI uri; 
    try { 
     uri = new URI("ws://websockethost:8080"); 
    } catch (URISyntaxException e) { 
     e.printStackTrace(); 
     return; 
    } 

    mWebSocketClient = new WebSocketClient(uri) { 
     @Override 
     public void onOpen(ServerHandshake serverHandshake) { 
      Log.i("Websocket", "Opened"); 
      mWebSocketClient.send("Hello from " + Build.MANUFACTURER + " " + Build.MODEL); 
     } 

     @Override 
     public void onMessage(String s) { 
      final String message = s; 
      runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        TextView textView = (TextView)findViewById(R.id.messages); 
        textView.setText(textView.getText() + "\n" + message); 
       } 
      }); 
     } 

     @Override 
     public void onClose(int i, String s, boolean b) { 
      Log.i("Websocket", "Closed " + s); 
     } 

     @Override 
     public void onError(Exception e) { 
      Log.i("Websocket", "Error " + e.getMessage()); 
     } 
    }; 
    mWebSocketClient.connect(); 
} 

per inviare un messaggio:

public void sendMessage(String message) { 
    mWebSocketClient.send(message); 
} 

ref: https://github.com/elabs/mobile-websocket-example

+0

Posso inviare un file xml usando android a php? –

+0

Sì, è possibile inviare come stringa. –

1

Se si desidera saltare quello che ho scritto, ecco un download un socket server PHP completamente funzionante e un client socket Android (con tutto il codice sorgente): http://developersfound.com/PHP_SocketServer_Android_SocketClient.zip

O per le informazioni che si possono trovare lettura utile su ....

Un importante regola qui è quello di capire le differenze tra il ‘/ modello di risposta richiesta HTTP’ e il modello TCP. Il vantaggio di TCP su HTTP è che è possibile accodare messaggi e sfruttare il full duplex (comunicazione simultanea bidirezionale), anche le connessioni TCP aperte sono un po 'più reattive. A meno che la tua soluzione non richieda assolutamente l'accodamento o i vantaggi di full duplex, dovresti utilizzare RPC su HTTP o REST. L'HTTP è molto più facile da implementare e più affidabile sui dispositivi mobili. Lo spostamento di lunghe distanze su dispositivi mobili tende a interrompere le connessioni TCP e quando la connessione viene interrotta si perde la coda e si deve riconnettere. La riconnessione richiede anche molta più energia della batteria e può bloccare il sistema client. Un altro svantaggio è che un sistema live può finire con un sacco di connessioni live e rallentare i server in modo significativo; più di un server HTTP occupato.

Tuttavia se la soluzione ha bisogno, o beneficia dei vantaggi del protocollo TCP, continua a leggere ....

Questo codice di base (nel link qui sotto) ha una completamente funzionale (autonomo) del server PHP e completamente client socket Android funzionale. Questa base di codice dovrebbe fornire un valido riferimento per l'implementazione di socket client in Android. Questo codice base è implementato in conformità con le best practice di Android e funge da riferimento forte per l'implementazione del processo a lungo termine per la stabilità.

È interessante notare che i documenti Android consigliano di utilizzare i servizi per implementare i socket in quanto non è possibile analizzare i socket. Per questo motivo è necessario un modello di tipo singleton. Si noterà che questo codebase utilizza AIDL per comunicare con il servizio e le trasmissioni per aggiornare l'interfaccia utente. Questa è la migliore pratica in quanto i socket devono essere protetti dalla garbage collection e dalla ricreazione delle attività, che normalmente interromperà le connessioni socket. I servizi associati tramite AIDL e Thread Executor sono tutti associati alle migliori pratiche per la stabilità dei processi di lunga durata.

Spero che questo aiuti.