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;
To build this example, ensure that you have the ØMQ adabindings installed and run the following:
gprbuild -p -P zmq-examples
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.