4

I have a application running that's listing to HTTP request. Each request is passed to single page where a framework object $app is instantiated and this takes care of routing / controller / model etc.

Now i have a another class whose object is instantiated via. a CLI script lets call it $cliApp now problem is how do i make both the object talk to each other. $app is instantiate every-time there is a new request.

But $cliApp is instantiate only once when script is ran. This scripts runs in loop via $loop object by PHP React Event loop.

Cli App is running websockets. So basically i want http & sockets to communicate via. http api.

P.s. :

Right now i have one solution to use message queueing e.g. 0mq etc. but that seems overkill since i'm not looking to scale and keep it simple.

Another solution i'm currently trying and feels right is to share a SptStorageObject between threads created by $http request and thread created by $cli request. Maybe this is question of dependency injection and i'm having troubles to share this $store object.

kishanio
  • 6,979
  • 8
  • 25
  • 33
  • Every request to your app starts a new thread on the server. The CLI does the same. Threads in PHP do never share anything. You need a messaging system to achieve communication. So you are on the right track. – colburton Apr 25 '16 at 12:37
  • I'm not entirely sure if I understand how many processes are being run here. Basically do you start-up one instance of the PHP process (the react http server) and the $cliApp is WITHIN this? or are there multiple instances of php getting spawned here? – Method Apr 26 '16 at 14:54
  • @Method I'm just using React Event Loop & Ratchet Websockets. HTTP request come along another framework i.e. using symfony/silex components. – kishanio Apr 27 '16 at 08:52
  • @colburton is it possible to share storage object between two? If so can you guide me please. I want to instantiate this storage object once and share it between 2? – kishanio Apr 27 '16 at 09:13
  • Object sharing is not possible in PHP. This is by design. Solutions involve some other services like Redis or Memcache. If you have open connections to your clients (Websockets) you might consider Redis, since it provides "channels" which can inform you about changes to your stored data without your script polling every second. – colburton Apr 27 '16 at 09:23
  • Even if your scripts are started by something like "fork" they never share any resources. – colburton Apr 27 '16 at 09:25
  • @colburton yes i'm using zeromq to achieve same but i'm constrained by a requirement that i can't use external libraries that would require maintenance and also keep design simple. Right now i'm experimenting to create a static class using a `SplObjectStorage` and use it between HTTP & CLI do you think that would work. I don't feel its clean approach though? Ofcourse intuitively it feels won't work. As you said you can't share things around right. – kishanio Apr 27 '16 at 09:28

1 Answers1

3

If I understand correctly, you have (assumptions noted):

  • a normal PHP web app that communicates over HTTP (presumably on Apache or similar webserver)
  • a long-running PHP cli app that communicates over websockets.

Presumably both apps are receiving communication from web clients on an ongoing basis. Presumably they also have their own persistent data stores, such as a MySQL database or similar, perhaps even sharing the same one.

I'm going to assume that what you need goes beyond each application accessing the most up-to-date data from the persistent data store (or that the two processes use separate data stores), and you actually need on-demand communication between the two processes.

You're on the right path with message queues, but as you note it's needless complexity to add a third dedicated inter-process communication layer when you've already got two communication layers that work perfectly fine on their own.

What you need is for your cli app to speak HTTP when it needs to initiate communication with your web app, and for your web app to speak web sockets when it needs to initiate communication with your cli app.

What this looks like in practice is fairly simple.

In your cli app, just use cURL to initiate an HTTP connection to your web app. This is fairly simple, there are endless resources out on the web to help you along the way and if you get stuck then coming here with a new question specific to your problem will get you going. All this requires in your web app is the following:

  • appropriate endpoint(s) which the cli app can send requests to, if the basic client facing pages won't suffice
  • some method to authenticate the cli app if it needs to access data that should not be available to web clients

For your web app to initiate a websocket connection to the cli app, it's a bit more complicated because I'm not aware of any native PHP functionionality that specifically targets the websocket protocol. However, I did find this (extremely permissive) github project that purports to give you the ability to set up a web socket server, and it also includes a client script that you could use to connect to and send/receive data while your web app process lives, and then shut it down when you're done. It appears to still have some minimal activity, you could use that directly or use it as a starting point to write your own websocket client.

In this case, just as in the reverse situation, you need the cli client to recognize and authenticate traffic from your web client so it can serve appropriate data just to it.

If for some reason this scenario won't work for you, then you're back to message queues or shared data stores (someone suggested redis, which can act as a hybrid data store/message queue under some circumstances).

Jason
  • 13,606
  • 2
  • 29
  • 40