Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Socket with android

I would like to ask how to create a PHP socket which able receive request from android phone in real time? For now, i done this part of code and able test it using telnet. However, when the android phone try to connect, it unable receive or send anything to server.

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);
like image 411
Matthew Chin Avatar asked Mar 20 '15 04:03

Matthew Chin


People also ask

How to implement socket in Android?

Step 1 − Create a new project in Android Studio, go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml. Step 3 − Add the following code to res/layout/MainActivity.

Can I use socket IO with PHP?

For 'long-lived connection' , you can use Ratchet for PHP. It's a library built based on Stream Socket functions that PHP has supported since PHP 5. For client side, you need to use WebSocket that HTML5 supported instead of Socket.io (since you know, socket.io only works with node. js).

Can PHP use WebSocket?

You can decide to use any WebSocket-based protocol that supports PHP.

What is WebSocket Android?

The App Socket library allows for the creation of sockets between Android applications. This allows for the creation of Client-Server style applications among Android applications. Once the socket are connected, applications can share data with one another over these sockets.


2 Answers

Add this library in build.gradle.

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

to connect:

 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();
}

to send message:

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

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

like image 70
Selim YILDIZ Avatar answered Sep 23 '22 15:09

Selim YILDIZ


If you want to skip what I’ve written, here’s a download to a fully working PHP socket server and Android socket client (with all the source code): https://developersfound.com/PHP_SocketServer_Android_SocketClient.zip

Or for information that you may find useful read on ....

An important rule of thumb here is to understand the differences between the ‘HTTP request/response model’ and the TCP model. The advantage of TCP over HTTP is that you can queue messages and take advantage of full duplex (two way simultaneous communication), also open TCP connections are a bit more responsive. Unless your solution absolutely needs queuing and or benefits from full duplex you should actually be using RPC over HTTP or REST. HTTP is much easier to implement and more reliable on mobile devices. Moving long distances on mobile devices, tends to break TCP connections and when the connection is broken you lose any queuing and have to reconnect. Reconnecting also takes up a lot more battery power and can hang the client system. Another disadvantage is that a live system can end up with a lot of live connections and slow your servers quite significantly; more so than a busy HTTP server.

However if your solution needs, or benefits from the advantages of TCP, read on ....

This code base (in the link above) has a fully functional (self contained) PHP server and a fully functional Android socket client. This code base should provide a strong reference for implementing client sockets in Android. This code base is implemented in accordance with Android best practices as well as serving as a strong reference for implementing long running process for stability.

It is noteworthy to understand that the Android docs recommend using Services to implement sockets because sockets cannot be parsed. For this reason a singleton type model is necessary. You will notice that this codebase uses AIDL to communicate with the service and broadcasts to update the UI. This is best practice as sockets must be protected from garbage collection and activity recreation, which would normally break the socket connections. Services bound through the AIDL and Thread Executors are all associated with best practices for the stability of long running processes.

Hope this helps.

like image 32
user2288580 Avatar answered Sep 25 '22 15:09

user2288580