Skip to content

Commit

Permalink
Added php haXe target code to integrate with php-zmq bindings.
Browse files Browse the repository at this point in the history
Added php - specific haXe code in the org.zeromq.ZMQ***.hx classes to wrap the php-zmq binding library.  This now allows php-targetted haXe applications to use the zeroMQ messaging library.

It was also necessary to re-write some of the unit test methods (in the org/zeromq/test folder) and guide applications to work with php.

Edited haxelib.xml file to update details of v1.1.0 hxzmq library
  • Loading branch information
rjsmith committed Jun 27, 2011
1 parent 8d4359e commit 766dc25
Show file tree
Hide file tree
Showing 27 changed files with 697 additions and 80 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@ test/out-cpp/Windows/*
test/out-neko/Linux/*
test/out-neko/Mac64/*
test/out-neko/Windows/*
test/out-php/Linux/*
test/out-php/Mac64/*
test/out-php/Windows/*
guide/out-cpp/Linux/*
guide/out-cpp/Mac64/*
guide/out-cpp/Windows/*
guide/out-neko/Linux/*
guide/out-neko/Mac64/*
guide/out-neko/Windows/*
guide/out-php/Linux/*
guide/out-php/Mac64/*
guide/out-php/Windows/*
46 changes: 39 additions & 7 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ To just build or just use hxzmq in a haXe project, you will need a working 0MQ l
There are [lots of instructions on the zeromq website][1].

To actually build hxzmq from source, you will need some additional installation steps:
### HXCPP (all platforms)
The hxzmq repository uses the hxcpp build tool to compile hxzmq.ndll from source on all target platforms, for neko and cpp -based applications:.
### HXCPP (all OS, neko and cpp targets)
The hxzmq repository uses the hxcpp build tool to compile hxzmq.ndll from source on all target operating systems, for neko and cpp -based applications:.

1. You need to install the full hxcpp package on your development machine:
haxelib install hxcpp
Expand All @@ -26,6 +26,12 @@ To build hxzmq on Windows, you need to:
<compilerflag value = "-IC:\zeromq\zeromq-2.1.6\src" if="windows"/>
Both of these are necessary to build hxzmq on Windows, as it refers to header files contained in the libzmq distribution.
Note that if you build the debug target libzmq MSVC project, you may encounter errors related to a missing MSVCR100D.dll (debug c++ runtime).

## PHP-ZMQ (PHP target)
The haXe classes in the org.zeromq namespace (/org/zeromq in the project structure) include php - specific code to integrate the haXe ZMQ API with the [php-zmq PHP zeroMQ binding][3].

To use this, install the php-zmq extension following the instructions documented in the php-zmq project. Then compile your PHP - targetted haXe application code including the hxzmq library. Instead of using the hxzmq.ndll C wrapper, the haXe zeroMQ code redirects to the php-zmq class methods.

## hxzmq Library Installation using haxelib

To be able to just use hxzmq to build 0MQ messaging into new haXe applications,
Expand All @@ -38,7 +44,7 @@ without modifying the or re-building hxzmq from source, you need:
include the hxzmq library in your hxml haXe compilation file:
-lib hxzmq

3. To run your target executable, your system will need to reach the hxzmq.ndll library file
3. *(For neko and cpp targetted applications only)* To run your target executable, your system will need to reach the hxzmq.ndll library file
and the libzmq.dll 0MQ library file. Add both paths to your environment executable PATH variable or copy into a standard library path directory if not in one already (e.g. /usr/lib in linux),
or copy both files into the same folder as your newly-minted haXe executable
(e.g. either a neko .n or cpp executable).
Expand Down Expand Up @@ -73,10 +79,11 @@ or
or
haxe buildLinux.hxml

These create debug - enabled target cpp and neko executables in the test/out-cpp/... and test/out-neko/... folders.
These create debug - enabled target cpp, neko and php executables in the test/out-cpp/... , test/out-neko/... and test/out-php/... folders.
Then to run the test executables:

1. Navigate to the folder holding the test executable (cpp or neko, platform),
For neko and cpp:
1. Navigate to the folder holding the test executable (cpp or neko, OS-specific),
2. Ensure that the hxzmq.ndll and libzmq.dll files are on your executable path (or copied into this folder)
3. Run the program

Expand All @@ -86,6 +93,18 @@ e.g, to build and run the cpp unit test target executable on Mac64:
cd out-cpp/Mac64
./TestAll-debug

For php:
1. Navigate to the folder holding the test index.php file.
2. Ensure that the php-zmq extension is available (run `php -m` and look for `zmq`)
3. Run the program

e.g, to build and run the php unit test target executable on Mac64:
cd test
haxe buildMac64.hxml
cd out-php/Mac64
php -f index.php


You should see output similar to:
Class: org.zeromq.test.TestVersion TestVersion.hx:39: version_full:20107
..
Expand All @@ -112,19 +131,32 @@ or
or
haxe buildLinux.hxml

These create debug - enabled target cpp and neko executables in the guide/out-cpp/... and guide/out-neko/... folders.
These create debug - enabled target cpp, neko and php executables in the guide/out-cpp/... or guide/out-neko/... or guide/out-php folders.
Then to run the test executables:

For neko or cpp:
1. Navigate to the folder holding the guide executable (cpp or neko, platform),
2. Ensure that the hxzmq.ndll and libzmq.dll files are on your executable path (or copied into this folder)
3. Run the program

e.g, to build and run the neko unit test target executable on Windows:
e.g, to build and run the neko guide target executable on Windows:
cd guide
haxe buildWindows.hxml
cd out-neko/Windows
neko run-debug.n

For php:
1. Navigate to the folder holding the guide index.php
2. Ensure that the php-zmq extension is available (run `php -m` and look for `zmq`)
3. Run the program

e.g, to build and run the php guide target executable on Windows:
cd guide
haxe buildWindows.hxml
cd out-php/Windows
php -f index.php


[1]: http://www.zeromq.org/intro:get-the-software "ZeroMQ installation"
[2]: http://haxe.org/doc/cpp/ffi "HXCPP Build Tool"
[3]: http://github.com/mkoppanen/php-zmq
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ By Richard Smith [RSBA Technology Ltd] [1]

## Introduction
This repository provides C++ binding code that wraps the libzmq library API to create a Neko DLL file, hxzmq.ndll. The ndll is then accessed via the hxzmq org.zeromq package to expose the 0MQ API to haXe application code targetted at C++ or nekovm platforms.

Also included is wrapper code around the [existing PHP ZeroMQ binding] [12], enabling haXe programs compiled for the PHP environment can slso make use of zeroMQ socket technology.
### Background & Rationale
haXe enables applications to be written in a single unified programming language that can then be executed on any combination of an ever-growing number of [target language platforms.] [6]. It is quite possible to write back-end server code targetted at php or C++, with a rich internet application Flash or javascript front-end, plus an iPhone application (via the C++ target), all using a single shared haXe codebase. Code written using non-target specific APIs can be automatically re-used on any of these platforms, such as an application's internal domain model or framework code. Conditional compilation, together with many target - specific APIs contained in the [haXe standard library] [7], provides the opportunity to access platform-specific features, giving the best of both worlds. Most of the target platforms also support extending the standard capabilities by use of externs and Foreign Function Interface mechanisms; an ability which has been used to write hxzmq. haXe is an [open source project] [7].

Expand Down Expand Up @@ -131,7 +133,9 @@ Key files and folders contained in this repository:

## Versions

The current release of hxzmq is 1.0.0, compatable with libzmq-2.1.4 or any later 2.1.x version. The latest released hxzmq package shall also be available in the [haxelib repository] [4], accessable via the [haxelib tool] [5] which is included in the standard haXe distribution.
The current release of hxzmq is 1.1.0, compatable with libzmq-2.1.4 or any later 2.1.x version. The latest released hxzmq package shall also be available in the [haxelib repository] [4], accessable via the [haxelib tool] [5] which is included in the standard haXe distribution.

This version of hxzmq has also been tested against [php-zmq v0.7.0] [13]

## Building and Installation

Expand All @@ -158,6 +162,8 @@ included with the hxzmq distribution.
[9]: http://www.imatix.com/ "iMatix Corporation"
[10]: http://haxe.org/doc/cpp/ffi "C++ FC Foreign Function Interface"
[11]: http://zguide.zeromq.org/ "0MQ Guide"
[12]: http://github.com/mkoppanen/php-zmq
[13]: http://github.com/mkoppanen/php-zmq/blob/0.7.0



8 changes: 8 additions & 0 deletions guide/buildLinux.hxml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,11 @@
-debug
-main org.zeromq.guide.Run

# Build PHP guide target
--next
-cp ..
-php out-php/Linux
-debug
--remap neko:php
-main org.zeromq.guide.Run

8 changes: 8 additions & 0 deletions guide/buildMac64.hxml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@
-main org.zeromq.guide.Run

# todo: Neko Mac0SX 64 bit target

# Build PHP guide target
--next
-cp ..
-php out-php/Mac64
-debug
--remap neko:php
-main org.zeromq.guide.Run
8 changes: 8 additions & 0 deletions guide/buildWindows.hxml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,11 @@
-debug
-main org.zeromq.guide.Run

# Build PHP guide target
--next
-cp ..
-php out-php/Windows
-debug
--remap neko:php
-main org.zeromq.guide.Run

3 changes: 2 additions & 1 deletion haxelib.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<user name="rjsmith"/>
<tag v="cpp"/>
<tag v="neko"/>
<tag v="php"/>
<description>Haxe language binding for the ZeroMQ socket library</description>
<version name="1.0.0">Initial upload, compatable with libzmq 2.1.6+</version>
<version name="1.1.0">Added php target by integrating with php-zmq binding</version>
</project>
123 changes: 123 additions & 0 deletions org/zeromq/ZMQ.hx
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,11 @@ class ZMQ {
*/
public static function strError(e:Int):String
{
#if php
return _hx_zmq_str_error(e);
#else
return Lib.nekoToHaxe(_hx_zmq_str_error(e));
#end
}

/**
Expand Down Expand Up @@ -511,6 +515,125 @@ class ZMQ {
private static var _hx_zmq_ENOCOMPATPROTO = Lib.load("hxzmq", "hx_zmq_ENOCOMPATPROTO", 0);
private static var _hx_zmq_ETERM = Lib.load("hxzmq", "hx_zmq_ETERM", 0);

#elseif php
// Load functions and constants from php-zmq


private static function _hx_zmq_version_full():Int {
return untyped __php__('ZMQ::LIBZMQ_VER');
}
// Not supported in php-zmq 0.7.0
private static function _hx_zmq_version_major():Int {
throw new ZMQException(ENOTSUP);
return null;
}
// Not supported in php-zmq 0.7.0
private static function _hx_zmq_version_minor():Int {
throw new ZMQException(ENOTSUP);
return null;
}
// Not supported in php-zmq 0.7.0
private static function _hx_zmq_version_patch():Int {
throw new ZMQException(ENOTSUP);
return null;
}
// Not supported in php-zmq 0.7.0
private static function _hx_zmq_make_version(major:Int, minor:Int, patch:Int):Int {
throw new ZMQException(ENOTSUP);
return null;
}
// Not supported in php-zmq 0.7.0
private static function _hx_zmq_str_error(e:Int):String {
return "ZMQ Error"; // php-zmq doesnt expose the str_error function
}
private static function _hx_zmq_catch_signals():Void {
throw new ZMQException(ENOTSUP);
return null;
}
private static function _hx_zmq_interrupted():Int {
throw new ZMQException(ENOTSUP);
return null;
}


private static function _hx_zmq_ZMQ_PUB():Int {return untyped __php__('ZMQ::SOCKET_PUB');}
private static function _hx_zmq_ZMQ_SUB():Int {return untyped __php__('ZMQ::SOCKET_SUB');}
private static function _hx_zmq_ZMQ_PAIR():Int {return untyped __php__('ZMQ::SOCKET_PAIR');}
private static function _hx_zmq_ZMQ_REQ():Int {return untyped __php__('ZMQ::SOCKET_REQ');}
private static function _hx_zmq_ZMQ_REP():Int {return untyped __php__('ZMQ::SOCKET_REP');}
private static function _hx_zmq_ZMQ_DEALER():Int {return untyped __php__('ZMQ::SOCKET_XREQ');}
private static function _hx_zmq_ZMQ_ROUTER():Int {return untyped __php__('ZMQ::SOCKET_XREP');}
private static function _hx_zmq_ZMQ_PULL():Int {return untyped __php__('ZMQ::SOCKET_PULL');}
private static function _hx_zmq_ZMQ_PUSH():Int {return untyped __php__('ZMQ::SOCKET_PUSH');}


private static function _hx_zmq_ZMQ_LINGER():Int {return untyped __php__('ZMQ::SOCKOPT_LINGER');}
private static function _hx_zmq_ZMQ_HWM():Int {return untyped __php__('ZMQ::SOCKOPT_HWM');}
private static function _hx_zmq_ZMQ_RCVMORE():Int {return untyped __php__('ZMQ::SOCKOPT_RCVMORE');}
private static function _hx_zmq_ZMQ_SUBSCRIBE():Int {return untyped __php__('ZMQ::SOCKOPT_SUBSCRIBE');}
private static function _hx_zmq_ZMQ_UNSUBSCRIBE():Int {return untyped __php__('ZMQ::SOCKOPT_UNSUBSCRIBE');}
private static function _hx_zmq_ZMQ_SWAP():Int {return untyped __php__('ZMQ::SOCKOPT_SWAP');}
private static function _hx_zmq_ZMQ_AFFINITY():Int {return untyped __php__('ZMQ::SOCKOPT_AFFINITY');}
private static function _hx_zmq_ZMQ_IDENTITY():Int {return untyped __php__('ZMQ::SOCKOPT_IDENTITY');}

private static function _hx_zmq_ZMQ_RATE():Int {return untyped __php__('ZMQ::SOCKOPT_RATE');}
private static function _hx_zmq_ZMQ_RECOVERY_IVL():Int {return untyped __php__('ZMQ::SOCKOPT_RECOVERY_IVL');}
private static function _hx_zmq_ZMQ_RECOVERY_IVL_MSEC():Int {
throw new ZMQException(ENOTSUP);
return null;
}
private static function _hx_zmq_ZMQ_MCAST_LOOP():Int {return untyped __php__('ZMQ::SOCKOPT_MCAST_LOOP');}
private static function _hx_zmq_ZMQ_SNDBUF():Int {return untyped __php__('ZMQ::SOCKOPT_SNDBUF');}
private static function _hx_zmq_ZMQ_RCVBUF():Int {return untyped __php__('ZMQ::SOCKOPT_RCVBUF');}
private static function _hx_zmq_ZMQ_RECONNECT_IVL():Int {
throw new ZMQException(ENOTSUP);
return null;
}
private static function _hx_zmq_ZMQ_RECONNECT_IVL_MAX():Int {
throw new ZMQException(ENOTSUP);
return null;
}
private static function _hx_zmq_ZMQ_BACKLOG():Int {
throw new ZMQException(ENOTSUP);
return null;
}
private static function _hx_zmq_ZMQ_FD():Int {
throw new ZMQException(ENOTSUP);
return null;
}
private static function _hx_zmq_ZMQ_EVENTS():Int {
throw new ZMQException(ENOTSUP);
return null;
}
private static function _hx_zmq_ZMQ_TYPE():Int {return untyped __php__('ZMQ::SOCKOPT_TYPE');}

private static function _hx_zmq_ZMQ_POLLIN():Int {return untyped __php__('ZMQ::POLL_IN');}
private static function _hx_zmq_ZMQ_POLLOUT():Int {return untyped __php__('ZMQ::POLL_OUT');}
private static function _hx_zmq_ZMQ_POLLERR():Int {
throw new ZMQException(ENOTSUP);
return null;
}
private static function _hx_zmq_DONTWAIT():Int {return untyped __php__('ZMQ::MODE_NOBLOCK');}
private static function _hx_zmq_SNDMORE():Int {return untyped __php__('ZMQ::MODE_SNDMORE');}

// Use the ZMQ::ERR_ENOTSUP for any Exxxx codes not supported by php-zmq binding
private static inline function _hx_zmq_EINVAL():Int {return untyped __php__('ZMQ::ERR_ENOTSUP');}
private static inline function _hx_zmq_ENOTSUP():Int {return untyped __php__('ZMQ::ERR_ENOTSUP');}
private static inline function _hx_zmq_EPROTONOSUPPORT():Int {return untyped __php__('ZMQ::ERR_ENOTSUP');}
private static inline function _hx_zmq_EAGAIN():Int {return untyped __php__('ZMQ::ERR_EAGAIN');}
private static inline function _hx_zmq_ENOMEM():Int {return untyped __php__('ZMQ::ERR_ENOTSUP');}
private static inline function _hx_zmq_ENODEV():Int {return untyped __php__('ZMQ::ERR_ENOTSUP');}
private static inline function _hx_zmq_ENOBUFS():Int {return untyped __php__('ZMQ::ERR_ENOTSUP');}
private static inline function _hx_zmq_ENETDOWN():Int {return untyped __php__('ZMQ::ERR_ENOTSUP');}
private static inline function _hx_zmq_EADDRINUSE():Int {return untyped __php__('ZMQ::ERR_ENOTSUP');}
private static inline function _hx_zmq_EADDRNOTAVAIL():Int {return untyped __php__('ZMQ::ERR_ENOTSUP');}
private static inline function _hx_zmq_ECONNREFUSED():Int {return untyped __php__('ZMQ::ERR_ENOTSUP');}
private static inline function _hx_zmq_EINPROGRESS():Int {return untyped __php__('ZMQ::ERR_ENOTSUP');}
private static inline function _hx_zmq_EMTHREAD():Int {return untyped __php__('ZMQ::ERR_ENOTSUP');}
private static inline function _hx_zmq_EFSM():Int {return untyped __php__('ZMQ::ERR_EFSM');}
private static inline function _hx_zmq_ENOCOMPATPROTO():Int {return untyped __php__('ZMQ::ERR_ENOTSUP');}
private static inline function _hx_zmq_ETERM():Int {return untyped __php__('ZMQ::ERR_ETERM');}

#end
}

19 changes: 16 additions & 3 deletions org/zeromq/ZMQContext.hx
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,22 @@ class ZMQContext {
}
}


#if (cpp || neko)
private static var _hx_zmq_construct = neko.Lib.load("hxzmq", "hx_zmq_construct", 1);
private static var _hx_zmq_term = neko.Lib.load("hxzmq", "hx_zmq_term", 1);


#elseif php
private static function _hx_zmq_construct(ioThreads:Int):Dynamic {
// Implement this test explicitly as php-zmq doesnt seem to detect / trap it.
if (ioThreads == 0) {
throw ZMQ.errorTypeToErrNo(EINVAL);
return null;
}
return untyped __php__('new ZMQContext($ioThreads)');
}

private static function _hx_zmq_term(ctx:Dynamic):Void {
// Explicity destroy the php ZMQContext object (which invokes zmq_term in the php-zmq binding)
untyped __call__('unset', ctx);
}
#end
}
10 changes: 6 additions & 4 deletions org/zeromq/ZMQException.hx
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,21 @@ class ZMQException {

public var errNo(default,null):Int;

public function new(e:ErrorType) {
// Allows error string to be overriden on creation (e.g. for preserving php-zmq errors)
private var overriddenStr:String;

public function new(e:ErrorType, ?str:String ) {
this.err = e;
this.errNo = ZMQ.errorTypeToErrNo(err);
if (str != null) this.overriddenStr = str;
}

/**
* Returns ZMQ - specified human-readable error description
* @return
*/
public function str():String {
return ZMQ.strError(errNo);
return { if (overriddenStr != null) overriddenStr else ZMQ.strError(errNo); };
}

public function toString():String {
Expand All @@ -52,6 +56,4 @@ class ZMQException {
return b.toString();
}

//private static var _hx_zmq_strerror = neko.Lib.load("hxzmq", "hx_zmq_strerror", 1);

}
Loading

0 comments on commit 766dc25

Please sign in to comment.