0

I actually don't know whether I am asking a proper question. Let me describe my problem first.

End user <-1-> web server (by PHP) <-2-> an internal process (by C or C++) <-3-> an external hardware

The 1 should be something like ajax request. The 2 should be something like inter-process communication. The 3 should be uart RS232 communication.

The end user will request to change some settings on the hardware, then the request will propagate to the hardware. The hardware replies successful or failed, then the result will propagate back to the user. The hardware reply delay can be within 1 second.

So when the webserver receives ajax request from end user, it will hold and send an IPC request to the c/c++ program. The c/c++ program will send via UART and hold and wait for hardware to reply. For UART part, there's asynchronous uart model, so the c/c++ program won't need to continuously wait for the UART.

The webserver will wait until the c/c++ program returns (via IPC again), and then forward the result back to the end user.

Since the webserver has no memory, so there can't be any asynchronous things (as far as I understand).

I can think of a simple way which is via file or database. The webserver continuously reading files or database for reply.

But I don't really think this is a good way because it causes wasting of server CPU cycles.

If I can tolerate some delays, well, it depends, but I think several seconds of delay at user side is ok to them.

Can you suggest me some nice ways of IPC to achieve my purpose?

And, if you think there's a better solution (than my description above) for the whole process or any specific link (including link 1, 2 & 3), please also share your 2cent.

Hope I asked my question clearly.

Thanks.

user534498
  • 3,926
  • 5
  • 27
  • 52
  • 1
    To be clear: the C/C++ part, which communicates with the hardware, is it a running process (answering possibly several requests through link `2` or does it gets started on every new request to it? – h7r Feb 01 '15 at 09:53
  • you can use this https://github.com/krakjoe/pthreads and write the C++ part as a php module. – Casimir et Hippolyte Feb 01 '15 at 10:05
  • or you can use gearman: https://medium.com/@assertchris/gearman-in-your-sockets-eefe4f64de2f – Casimir et Hippolyte Feb 01 '15 at 10:12
  • Could d-bus or zero-mq work? – Paul Rooney Feb 01 '15 at 11:51
  • @h7r It is a stand-alone process, not a new one for each request. – user534498 Feb 01 '15 at 15:27
  • @PaulRooney thx, a little googling shows that they are likely to be what i'm looking for, or at least they will help me think whether the design has problem or not. I will look into them. – user534498 Feb 01 '15 at 15:31
  • http://stackoverflow.com/questions/4789720/communicate-c-program-and-php/ http://stackoverflow.com/questions/1746207/how-to-ipc-between-php-clients-and-a-c-daemon-server http://stackoverflow.com/questions/3324619/unix-domain-socket-using-datagram-communication-between-one-server-process-and – Bernardo Ramos Apr 15 '17 at 02:53

3 Answers3

1

Possibly the simplest solution you can find is to use pipes. The processes would have an open pipe for reading "calls" and answering them in the same fashion.

One possible way of setting this up is to have a pair of named pipes (mkfifo) in a specific or variable location. Such pipes are known to both this process and PHP. The process would block reading a loop for requests/commands in some textual "protocol" and write back to PHP through the other pipe. In this way both PHP and the external processes could be stopped/killed and restarted and the communications path would still be stable.

You might need to do something else in order to verify whether the process is actually running, if this is needed, but a simple "ping" command over this "protocol" would be enough.

This assumes:

  • you have the possibility of making improvements to the processes that communicates to the hardware (otherwise, your are bound to whatever it already offers)
  • you don't have high performance requirements (pipes are relatively slow)
  • there's no parallelism problem in case of concurrent accesses from the PHP script to process (unless you do some locking, 2 concurrent requests would be written mixed in the pipe)

There are off course other ways of achieving this, but I find hard to consider other way that is as simple as this. Queueing (d-bus, others), as suggested in some comments, are just building on top of this idea but adding more complexity IMHO, therefore, if no functionality provided by these other services is needed, pipes should be enough.

h7r
  • 4,944
  • 2
  • 28
  • 31
  • Thanks. I took whole day today to read the book , and there are plenty of ways to do this: pipe, fifo (named pipe), stream pipe, named stream pipe, message queue, shared memory. I found that named pipe (or probably named stream pipe which is bi-directional), or message queue are probably ok for my situation. I think in C/C++ they are ok to use, I am not sure about whether PHP can call these C funcitons. I will read d-bus etc. tools tomorrow to decide. Thanks a lot. – user534498 Feb 03 '15 at 11:39
1

Just my 2 cents (should be a comment but I don't have the reputation) use zeromq or some other well known queuing library for your ipc.

In theory it is really simple to use fifos and domain sockets, however, in practice there are a lot of edge cases that you would need to code for. For instance, high water mark, reconnecting etc.

GNSL
  • 101
  • 4
  • [nanomsg](http://nanomsg.org/documentation.html) is another option. It supports the `ipc://` transport that uses unix domain sockets. – Bernardo Ramos Apr 14 '17 at 20:21
0

You can also have a webserver in plain C!

Check mongoose and civetweb.

The first works on devices like ESP8266 and ESP32.

Mongoose is released under Commercial and GNU GPL v.2 open source licenses.

Civetweb uses a MIT license.

Bernardo Ramos
  • 4,048
  • 30
  • 28