1

I implemented Websockets in my server, it works great to communicate with the server itself, but it cannot connect directly do my Delhpi application, so I thought, "I'll just make Delphi send info to PHP, then make PHP push info to the client via Websocket!", GREAT! but it doesn't work.

I'm not sure why, but I think it has something to do with 2 sockets cannot be listening at the same time, so I think I need to use Threads or something like that.

On paper it looks easy, it looks like I just need to start a Thread with my function listening my Delphi application socket, and when it receives a message, I would send this to the parent process to push the message via websocket, but I cant help it but feel like there is something wrong with this tactic.

This is the code that reads from the socket of my Delphi app:

 <?php
/* Cliente */

function enviarPct($skt, $pacote){
    $msg = "$pacote\n";
    socket_write($skt, $msg, strlen($msg));
    echo "TX: $msg";
}

error_reporting(E_ALL);

echo "Conexao TCP/IP em PHP\n";

$address = "192.168.2.26";
$port = 63333;
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($sock, $address, $port);
socket_set_option($sock, SOL_SOCKET, SO_KEEPALIVE, 1);
echo "Conexao: $address:$port\n\n";

enviarPct($sock,"login||20||");
//$msg = "login||20||\n";
//echo socket_write($sock, $msg, strlen($msg));
//echo socket_write($sock, utf8_encode($msg), mb_strlen($msg, 'utf-8'));

echo "Reading response:\n\n";
while ($out = socket_read($sock, 2048)) {
    echo "RX: $out";
    $pct = explode('||', $out);
      if($pct[0]=='sucessoLogin'){
        if($pct[1]!= '-1'){
            enviarPct($sock, "solicitaControladoras||||");
        }
      }
}

//echo socket_read($sock, 2048);

echo "Fechando\n";
socket_close($sock);
?>

And Within the websocket aplication class, this funcion push messeges to the client, more specificaly that looping with "Im Waiting X Seconds"

/**
 * Start a child process for pushing data
 * @param unknown_type $client
 */
private function startProcess($client) {
    $this->console("Start a client process");
    $pid = pcntl_fork();
    if($pid == -1) {
        die('could not fork');
    }
    elseif($pid) { // process
        $client->setPid($pid);
    }
    else {
        // we are the child
        while(true) {

            // check if the client is connected
            if(!$client->isConnected()){
                break;
            }

            // push something to the client
            $seconds = rand(2, 5);
            $this->send($client, "I am waiting {$seconds} seconds");
            sleep($seconds);
        }
    }
}

So thats it, if somebody have an idea of what would work best for me I would be glad to listen.

balazs630
  • 3,421
  • 29
  • 46
João Eduardo
  • 738
  • 7
  • 21
  • I do not think that is a good approach. PHP was designed to be a plugin to HTTP servers and work with HTTP requests. So I think a good approach would be to make specific HTTP-based interface in PHP and make your Delphi program use that in standard HTTP-POST way attaching JSON or XML payloads. Read about REST HTTP or about SOAP – Arioch 'The Apr 15 '16 at 12:21
  • i think i've read about this, the thing is that i would like to do little to none changes to the delphi aplication, even mainly because im a web programmer and i dont wanna touch that delphi monster, my boss just asked me for a "simple" solution like this. – João Eduardo Apr 15 '16 at 13:00
  • If you are the web programmer - the more reasons for you to stick with web protocols, text-based and supported by firewalls/proxies. Of course granted that at very least you can recompile the Delphi app. If the latter is a black box for you that can absolutely not be touched - then no way, sure, but then "Delphi" tag on your questions seems wrong to me. If you can do nothing with Delphi-made app - then I hardly see why you bring this point to Delphi audience, all the advices we can give to change Delphi-made app would be non-applicable to your situation, right? – Arioch 'The Apr 15 '16 at 13:11
  • I read your original `I'll just make Delphi send info to PHP` like you at least considering changing the Delphi app. If not then what about `but it cannot connect directly do my Delhpi application` - why ??? and what does it mean `to communicate with the server itself` - what your server even communicates with then? what is the larger schemes, who starts connections with whom and who feeds whom with what kinds of data ? Maybe you can make and run some local `websocket-binary to http-json proxy` application, working in the same machine as the Delphi app itself ? – Arioch 'The Apr 15 '16 at 13:13
  • hmm you bring a fair point, i apologize. but reading my question again i realized that messed it up, what i really would like to mean is "How to make websocket read from Delphi aplication socket." – João Eduardo Apr 15 '16 at 13:36
  • hire a Delphi (or Lazarus) developer to make a local http proxy deamon, that would accept plain http/json/comet requests from PHP and would in turn pull raw binary data from Delphi/TCP-socket and translate it into text form. There are a number of libs to make http/json server in Delphi, like mORMot. Ask him to make a program designed for easy future updates of the protocol with Delphi-inexperienced crew like you. He would have to document for you how to extend the translating proxy and you would try doing it. I really do not think PHP and you are good tools for dealing with binary ad hoc data – Arioch 'The Apr 15 '16 at 13:54
  • But would that work in a full-duplex enviroment? cuz both the client will send requests to my aplication, and my aplication would have to send info for the client, BTW we have a delphi programmer, but he is a very busy guy, ill get to him soon about this. – João Eduardo Apr 15 '16 at 14:10
  • Depends upon how that bridge be coded, one way or two way. You would have to ping him often anyway with every new change in his binary protocol at least. IF he would invest his time into learning you how to take binary protocol from his sources and how to code the text proxy - this maybe would make your team more efficient in long run (after initial heavy investments, I agree). – Arioch 'The Apr 15 '16 at 14:34
  • I know little about your situation, but from personal perspective binary protocol need some practice in thinking at "CPU level", otherwise there can be problems with new Delphi version, changed compiler option, setup of different languages in different computers, etc. And worst of all you would not be able to debug it! However if you would make text bridge - then you would be able to debug the resulting HTTP/JSON stream with any sniffing proxy – Arioch 'The Apr 15 '16 at 14:35
  • there is a little discussion about a bi-directional HTTP http://stackoverflow.com/questions/12279063 – Arioch 'The Apr 15 '16 at 14:41
  • `...it looks like I just need to start a Thread with my function listening my Delphi application socket, and when it receives a message, I would send this to the parent process to push the message via…..` I could give sample from application on Delphi 7. This application is running as Windows Services – for servicing some remote client. It is start listening on specific port and IP address by using TTcpServer. As soon as new connection established, it’s create new Client thread (ClientSocket.GetThreadObject as tMyClientThread) with client without interrupting current connection. – Zam Apr 15 '16 at 19:04
  • I am not sure how you going to “keep connection alive” with PHP… Of course you could modify this application for start new session for each request… – Zam Apr 15 '16 at 19:05
  • nice that looks like it would help, i kind of done what i wanted already but i done it it the most Back-ass non-optimal way ever, i made the Process that coencts to the delphi socket write in a file a lsit of messeges to be send, and then i made the Websocket aplication to get the messeges and clean the list every second, it really works, but it is really weird. – João Eduardo Apr 15 '16 at 20:56

0 Answers0