2

Hi I am a newbie in these kind of stuff but here's what i want to do.

I am trying to implement a chat application in which users will send their queries from the website and as soon as the messages are sent by the website users.It will appear in the android mobile application of the site owner who will answer their queries .In short I wanna implement a live chat.

Now right now I am just simply trying to send messages from android app to php server. But when I run my php script from dreamweaver in chrome the browser keeps on loading and doesn't shows any output when I send message from the client.

Sometimes it happened that the php script showed some outputs which I have sent from the android(client).But i don't know when it works and when it does not.

So I want to show those messages in the php script as soon as I send those messages from client and vice versa(did not implemented the vice versa for client but help will be appreciated).

Here's what I've done till now.

php script:

 <?php

 set_time_limit (0);
 $address = '127.0.0.1';

 $port = 1234;

 $sock = socket_create(AF_INET, SOCK_STREAM, 0);
 socket_bind($sock, $address, $port) or die('Could not bind to address');
 socket_listen($sock);


 $client = socket_accept($sock);
 $welcome = "Roll up, roll up, to the greatest show on earth!\n? ";
 socket_write($client, $welcome,strlen($welcome)) or die("Could not send connect string\n");

do{
$input=socket_read($client,1024,1) or die("Could not read input\n");
echo "User Says:  \n\t\t\t".$input;

if (trim($input) != "")
    { 
    echo "Received input: $input\n";
    if(trim($input)=="END")
    {
        socket_close($spawn);
        break;
    }
}
else{

$output = strrev($input) . "\n"; 
socket_write($spawn, $output . "? ", strlen (($output)+2)) or die("Could not write output\n");              
echo "Sent output: " . trim($output) . "\n";

}
}
while(true);


socket_close($sock);
echo "Socket Terminated";
?>

Android Code:

  public class ServerClientActivity extends Activity {
   private Button bt;
   private TextView tv;
   private Socket socket;
   private String serverIpAddress = "127.0.0.1";

   private static final int REDIRECTED_SERVERPORT = 1234;

   @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    bt = (Button) findViewById(R.id.myButton);
    tv = (TextView) findViewById(R.id.myTextView);

    try
    {
        InetAddress serverAddr = InetAddress.getByName(serverIpAddress);
        socket = new Socket(serverAddr, REDIRECTED_SERVERPORT);
    } 
    catch (UnknownHostException e1) 
    {
        e1.printStackTrace();
    }
    catch (IOException e1)
    {
        e1.printStackTrace();
    }


    bt.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
           try
           {
              EditText et = (EditText) findViewById(R.id.EditText01);
              String str = et.getText().toString();
              PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
              out.println(str);
              Log.d("Client", "Client sent message");
           }
           catch (UnknownHostException e)
           {
              tv.setText(e.getMessage());
              e.printStackTrace();
           }
           catch (IOException e) 
           {
              tv.setText(e.getMessage());
              e.printStackTrace();
           }
           catch (Exception e) 
           {
              tv.setText(e.getMessage());
              e.printStackTrace();
           }
        }

     });       

   }
 }

I've just pasted the onclick button event code for Android.Edit text is the textbox where I am going to enter my text. The ip address and port are same as in php script.

Mj1992
  • 3,404
  • 13
  • 63
  • 102
  • This may be a bit off topic you could get some inspiration and useful advice here in my previous post. https://stackoverflow.com/questions/29159354/php-socket-with-android/45851814#45851814 And here is a download to some very useful code that may help you. http://developersfound.com/PHP_SocketServer_Android_SocketClient.zip – user2288580 Aug 24 '17 at 02:04

4 Answers4

1

First of all - your server will handle only one client connection at a time, which doesn't makes sense for chat.

I can't see how you deal with socket connection on Android side but anyway it will not allow you to connect again as long as your script execution will not execute "socket_accept()" and wait for connection.

You should run 1 loop process to grab new client connections and fork into separate process each connected client.

Take look at my same lightweight PHP server I wrote here which is based on the same principle: https://github.com/webdevbyjoss/Aaaaa---space-ships-combat-multiplayer-game/blob/master/server/server.php

Ignore the Websockets related "doHandshake()" and "WebSocketFrame::decode/WebSocketFrame::encode" but you should be OK with the rest.

Generally it runs the loop

while (true) 

    if (($msgsock = socket_accept ( $sock )) === false) {
        echo "socket_accept() failed: reason: " . socket_strerror ( socket_last_error ( $sock ) ) . "\n";
    break;
    }

    // We got a client connected, lets process it in separate thread
    if (($pid = pcntl_fork()) === -1) {
        echo "pcntl_fork() failed. Make sure you are on Linux sustem, but not on Windows\n";
        break;
    }

    if (!$pid) { // client
        handleClient($msgsock);
        exit();
    }

    // parent server will wait to accept more clients connections in new loop
}

And inside handleClient() function you should have a separate loop to communicate with the client.

while (true) {
    if (false === ($buf = socket_read ( $msgsock, 2048, PHP_BINARY_READ ))) {
        echo "socket_read() failed: reason: " . socket_strerror ( socket_last_error ( $msgsock ) ) . "\n";
        return;
    }

    if (empty($buf)) { // do disconnection check
        echo "Client disconnected\n";
        return;
    }

   // -------------------------------------------------------------
   // PUT YOUR BUSINESS LOGIC HERE
   // TO HANDLE MESSAGES OF THE CHAT AND GENERATE RESPONSE TO USER
   // I RECOMMEND TO USE SOMETHING LIKE MEMCACHE/REDIS/MONGO/MYSQL/TXT-FILES
   // FOR MULTIPROCESS DATA INTERCHANGE
   // -------------------------------------------------------------

// transfer data to client
    socket_write($msgsock, $returnText, strlen($returnFrame));
}

socket_close ( $msgsock );
webdevbyjoss
  • 504
  • 7
  • 20
  • thnx for the reply I am using Windows.So does that make any difference as you've written in the code that must be using linux? – Mj1992 Jun 26 '12 at 08:14
  • the same problem is occuring the page keeps on loading and when i send messages from android client it does not do anything just keeps on loading the page.I've updated the android code. – Mj1992 Jun 26 '12 at 08:31
  • 1
    `stream_select` > `pcntl_fork`. Time to learn some event driven programming. – Leigh Jun 26 '12 at 10:14
  • yeah, worth to look into event driven programming in PHP thanks for pointing out! – webdevbyjoss Jun 26 '12 at 10:40
  • can you explain more about event driven programming in this situation? – Mj1992 Jun 27 '12 at 17:00
1

I'd recommend using an event driven framework for handling your connections.

There's a fairly decent example called React but it has tons of other stuff in there you'll probably want to strip out so your app doesn't depend on hundreds of external components.

React uses a message loop based on libevent if you have it installed, or stream_select otherwise.

You handle events with closures, something like:

    $client->on('read', function($data) use ($client) {
        $client->onRead($data);
    });

With this you will be able to handle lots of simultaneous connections, and it will not tie up all of your CPU.

Your code will be executed when something happens.

If nothing else, have a look at how it works, you'll get a better understanding of how to create a non-blocking event driven socket server.

Leigh
  • 12,859
  • 3
  • 39
  • 60
0

Have you tried adding '\r\n' into value of EditText before sending to server yet? I think the problem isn't connection between client and server because it doesn't show error when connection fail.
Maybe in your case socket_read($client,1024,1) must stop reading at a '\r\n'.

Update: Your local ip maybe cause connection error. Have a look at this link

Community
  • 1
  • 1
ductran
  • 10,043
  • 19
  • 82
  • 165
  • @Mj1992: I have updated my answer. You should write log when connection fail and update your question with logcat, especially when create new socket in android side. – ductran Jun 26 '12 at 09:14
0

Your address 127.0.0.1 will resolve to the machine the code is running on. So the app actually tries to connect to itself. type ipconfig /all on the MSDOS console and use that address instead.

TheRealChx101
  • 1,468
  • 21
  • 38