Source Code

http://github.com/persan/zeromq-Ada

Development environment

Linux

A modern gcc/gnat such as http://libre.adacore.com installed.

Or GCC 4.5 or better with Ada.

Windows

A modern gcc such as http://libre.adacore.com installed.

A set of posix build tools such as cygwin, with cygwin do not install gcc or have GNAT before it in the PATH.

Build and installation

You will first need to install the latest ØMQ from the development trunk here:

http://github.com/sustrik/zeromq2

Then download the zeromq-Ada source and cd to its top-level directory:

$ cd zeromq-Ada

Compile the stuff

$make

Finally install the package by running:

$ make install

You may have to run this last command with sudo .

Windows

Exact the same but you need ether cygwin or mingw as build environment

Sample code

A simple client/server application

This example implements a simple "SQL server" following the client/server model. The server listens to requests using unicast TCP. Each request is a simple string. Upon receiving a request the server will send back a canned response of OK , also as a string. All the samples are part of the package.

The server application, using Ada bindings:

with ZMQ.Sockets; with ZMQ.Contexts; with ZMQ.Messages; with Ada.Text_IO; use Ada.Text_IO; procedure ZMQ.examples.Server is ctx : ZMQ.Contexts.Context; s : ZMQ.Sockets.Socket; resultset_string : constant String := "OK"; begin -- Initialise 0MQ context, requesting a single application thread -- and a single I/O thread ctx.Initialize (1); -- Create a ZMQ_REP socket to receive requests and send replies s.Initialize (ctx, Sockets.REP); -- Bind to the TCP transport and port 5555 on the 'lo' interface s.Bind ("tcp://lo:5555"); loop declare query : ZMQ.Messages.Message; begin query.Initialize; -- Receive a message, blocks until one is available s.recv (query, 0); -- Process the query Put_Line (query.getData); declare -- Allocate a response message and fill in an example response resultset : ZMQ.Messages.Message; begin resultset.Initialize (query.getData & "->" & resultset_string); -- Send back our canned response s.Send (resultset); resultset.Finalize; end; query.Finalize; end; end loop; end ZMQ.Examples.Server;

The client application, using Ada bindings:

with ZMQ.Sockets; with ZMQ.Contexts; with ZMQ.Messages; with Ada.Text_IO; use Ada.Text_IO; procedure ZMQ.examples.Client is ctx : ZMQ.Contexts.Context; s : ZMQ.Sockets.Socket; begin -- Initialise 0MQ context, requesting a single application thread -- and a single I/O thread ctx.Initialize (1); -- Create a ZMQ_REP socket to receive requests and send replies s.Initialize (ctx, Sockets.REQ); -- Bind to the TCP transport and port 5555 on the 'lo' interface s.Connect ("tcp://localhost:5555"); for i in 1 .. 10 loop declare query_string : constant String := "SELECT * FROM mytable"; query : ZMQ.Messages.Message; begin query.Initialize (query_string & "(" & i'Img & ");"); s.Send (query); query.Finalize; end; declare resultset : ZMQ.Messages.Message; begin resultset.Initialize; s.recv (resultset); Put_Line ('"' & resultset.getData & '"'); resultset.Finalize; end; end loop; end ZMQ.Examples.Client;

Finally the multi-threaded server

with ZMQ.Sockets; with ZMQ.Contexts; with ZMQ.devices; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; procedure ZMQ.examples.Multi_Thread_Server is task type server_task (ctx : not null access ZMQ.Contexts.Context; id : Integer) is end server_task; task body server_task is msg : Ada.Strings.Unbounded.Unbounded_String; s : ZMQ.Sockets.Socket; begin s.Initialize (ctx.all, Sockets.REP); s.Connect ("inproc://workers"); loop msg := s.recv; Append (msg, "<Served by thread:" & id'Img & ">"); s.Send (msg); end loop; end server_task; ctx : aliased ZMQ.Contexts.Context; Number_Of_Servers : constant := 10; servers : array (1 .. Number_Of_Servers) of access server_task; workers : ZMQ.Sockets.Socket; clients : ZMQ.Sockets.Socket; dev : ZMQ.devices.device; begin -- Initialise 0MQ context, requesting a single application thread -- and a single I/O thread ctx.Initialize (servers'Length + 1); -- Create a ZMQ_REP socket to receive requests and send replies workers.Initialize (ctx, Sockets.XREQ); workers.Bind ("inproc://workers"); -- Bind to the TCP transport and port 5555 on the 'lo' interface clients.Initialize (ctx, Sockets.XREP); clients.Bind ("tcp://lo:5555"); for i in servers'Range loop servers (i) := new server_task (ctx'Access, i); end loop; dev.initialize (devices.Queue, clients, workers); end ZMQ.Examples.Multi_Thread_Server;

gprbuild -p -P zmq-examples

To build this example, ensure that you have the ØMQ adabindings installed and run the following:

You can then run bin/server and bin/client .

Documentation

The README file of the source code is the best documentation for now.

Test Suite

zeromq-Ada has an integrated test suite, to be completed!

$ make test

Bug Reporting

If you encounter problems please fill a bug report at:

http://github.com/persan/zeromq-Ada/issues

Discussions about this language binding take place on the general zeromq-dev list.