Communicating Between Ruby and PHP Using Named Pipes

Creating The Named Pipe

Through the mkfifo command we can create a named pipe which allows us to communicate locally between processes as if we were simply writing to a regular file descriptor. To do this simply type mkfifo
like below:

  $ mkfifo pipe

Ruby Server

Next we need a long standing daemon to process the communication, this could be python, ruby, php, or anything you like. First we require the JSON gem, then we open the pipe using 'r+' which will not block. Then we need to trap :TERM so that we can clean up by closing our pipe, then exit. (this could of course be much more elaborate)

require 'rubygems'
require 'json'

pipe = File.open 'pipe', 'r+'

trap :TERM do
  pipe.close
  exit 1
end

loop do
  p JSON.parse(pipe.gets)
end

Ruby Client

Next we have our ruby client, which will simply open the pipe for writing, and call #puts which forces flushing due to the newline, writing a string of JSON for our server to parse.

open 'pipe', 'w+' do |file|
  file.puts '{ "message": "im from ruby" }'
end

PHP Client

This is essentially the same as our ruby client, however now our JSON data is coming from PHP! super lame!

<?php

$pipe = fopen('pipe', 'r+');
fwrite($pipe, "{ \"message\": \"im from php\" }\n");
fclose($pipe);

Named Pipe Usage Example

Now lets test it out! open up your terminal window and execute the following commands,
run the clients as many times as you like :). kill defaults to TERM however we could use kill -TERM 437 as well.

  $ ruby server.rb &
[1] 437

  $ ruby client.rb
{"message"=>"im from ruby"}

  $ php client.php
{"message"=>"im from php"}

  $ kill 437