2

tl;dr: What is the best approach to keep a PHP Socket unblocked by MySQL Operations?

Basic Goal: Have a PHP+JAXL (XMPP) Socket listen, read and write via a persistent TCP Connection to Googles CCS GCM Server. This was accomplished using this CODE.

  • Now I need to Process Data (mostly MySQL) without blocking the Socket.

What have i thought of:

1: Have the Socket and the DB connection in two different PHP Threads. Communication could work via JobQueues. Implementations I found based on Geaman, Resque, BeanStalkD. These work however, mostly with a Master and Worker thread, so no bidirectional communication.

2: Implement a basic Queue as a global? Variable, Read Jobs from the DB thread, and put them back into another queue. (No idea whether smth lk this is possible)

3: Fork child processes like proposed in here. I would then have to open a DB connection everytime I fork, which I thought I could avoid in some way. Also, how to call send() from child?.

Hard Parts:

1: Two-way communication required: DB Thread has to send results to Socket

2: should work on Shared Hosting, e.g no Gearman, Redis installation. also: no PHP skills

What am I asking?:

  • What is needed to not block the Socket, and what not?

  • Which approach is suited for my needs, especially when my DB-Thread has to assign jobs to the Socket ("send xy")?

  • What am I understanding wrong here?

As you can see I lack the basic understanding, any guidance is very appreciated. Thanks alot.

Community
  • 1
  • 1
user2965003
  • 326
  • 2
  • 11
  • Typically to communicate with GCM, you should have a separate process doing so. It is not recommanded to do that from PHP. If you do not want to write a push server, you can use a third-party service for push. – Mickaël Rémond Jan 25 '15 at 20:44
  • The Xmpp Socket is already running, written in PHP. I can receive and send Messages to GCM and handle ACKs. I linked the Code above, it works like: `$GCMSender = new GCMSender(); $GCMSender->processGCMs();` I dont understand how I can process the messages "off-thread" and send back messages. – user2965003 Jan 26 '15 at 11:57

3 Answers3

2

All roads lead to Rome, but perhaps using React PHP is a solution for you.

It's an event-driven, non-blocking I/O library for PHP. It can handle your requirements, plus you don't have to dive into specifics to get the job done.

Jasper N. Brouwer
  • 21,517
  • 4
  • 52
  • 76
2

While its possible to write asynchronous queries with MySQLi, you can't just bundle it up with your network resources in the same *_select() call. However you could (in the same script) poll an asynchronous query. Just set a short timeout in socket_select() and in the same loop add a check for any completed mysql queries. Something like...

$wait=0;
while (true) {
    if (socket_select($netread, $netwrite, $netexcept
        , 0, $wait)) {
        // =...handle socket stuff
        $wait=200;
    }
    if (mysqli_poll($dbread, $dberror, $dbreject
         , 0, 0)) {
       //...handle mysql stuff
       $wait=0;
    }
}

(setting the wait to a non-zero value prevents the process eating all the CPU while doing nothing) Alternatively you could use a SIGALARM to trigger the polling.

symcbean
  • 47,736
  • 6
  • 59
  • 94
1

Look this version of dnode for PHP:

https://github.com/bergie/dnode-php

useful to make process to comunicate