您的位置:首页 > 编程语言 > Delphi

0MQ绑定Delphi版-说明

2016-10-30 17:50 106 查看

0MQ绑定Delphi版

这是一份ZMQ绑定。测试环境Delphi7,BDS2006,FPC 2.6.0(目前仅Window)。

概述

程序包中含有一个dll的wrapper(zmq.pas),和一个高层API(zmqapi.pas)。

它应该能够工作于ZMQ 2.2.0,和3.2.0 rc1(实验性)。要使用v3.2的dll,在zmq.inc中定义zmq3(
{$define zmq3}
)。dll来自于官方发行版

使用

你应该使用高层API,那会节省你大量时间,而且附带效果是代码也将更容易阅读。

首先,你应该创建一个上下文

<!--lang: delphi-->
context := TZMQContext.Create;

有很多种套接字类型,参见指南,每种都有一个常量。要创建例如一个REP套接字,这么写:

<!--lang: delphi-->

socket := context.Socket( stRep );

// 绑定套接字
socket.bind( 'tcp://*:5555' );

// 连接套接字
socket.connect( 'tcp://localhost:5555' );

API中有很多中方法来发送消息。你可以发送单份,或多份消息,阻塞或非阻塞(v3中称为dontwait不等待)模式。

<!--lang: delphi-->

// 阻塞模式(默认)发送一个字符串就像这么简单:
socket.send( 'Hello' );

// 或者用非阻塞模式
socket.send( 'Hello', [rsfNoBlock] );
// 这种情况下如果消息无法入队则将抛出一个EZMQException异常,
// 异常类型为EAGAIN。

// 从stream发送数据(别忘了设置stream的位置到读取位置)
socket.send( stream, size );

// 发送多段消息。
// 多个字符串:
socket.send( ['Hello','World'] );

// 这等同于:
socket.send( 'Hello', [rsfSndMore] );
socket.send( 'World' );

// 或者使用TStrings。
tsl := TStringList.Create;
tsl.Add( 'Hello' );
tsl.Add( 'World' );
socket.send( tsl );
tsl.Free;

接收消息就像这么容易:

<!--lang: delphi-->

msize := socket.recv( msg );
// 新的消息到了msg中,而msize持有消息的长度

// 到一个stream中
msize := socket.recv( stream );

// 读取多段消息
tsl := TStringList.Create;
mcount := socket.recv( tsl );
// 这将会添加多个消息的部分到字符串列表,并返回接收的消息数量。

CTRL+C的处理

这是个小技巧。在Windows中信号处理与posix系统有所不同。阻塞调用不会接收到SIGINT,只会持续的阻塞。要克服这个问题,已安装的处理器终止了上下文,所以阻塞调用例如
recv
poll
,等等...将接收到
ETERM
。这仅在Windows。

如果你将你的无限循环代码写为这样,你可以很干净的终止。

<!--lang: delphi-->

while not context.Terminated do
try
socket.recv( msg );
except
// 处理异常,或者
context.Terminate;
end;

context.Free;

轮询

轮询可以工作在两种不同方式,让我们称第一种为同步,第二种为异步方式。异步版本创建了一个线程,在其中做轮询。

同步

<!--lang: delphi-->

// 创建上下文 context := TZMQContext.Create; socket := context.Socket( stDealer ); socket.connect( address );

// 创建轮询器。参数true告诉轮询器使用同步轮询 poller := TZMQPoller.Create( true );

// 注册套接字。 poller.register( socket, [pePollIn] );

timeout := 100; // 100ms while not context.Terminated do begin

rc := poller.poll(timeout);
if rc > 0 then
do something...

end;

poller.Free; socket.Free; context.Free;

异步方式

这个实现使用了一种reactor模式,轮询器启动了一个新的线程,并在类和创建的线程之间创建了一对套接字连接。所以这个轮询器的实现不是线程安全的,不要在不同线程中去注册、反注册套接字。

<!--lang: delphi-->

procedure TMyClass.pollerEvent( socket: TZMQSocket; event: TZMQPollEvents );
begin
do something...
end;

// 创建上下文。
context := TZMQContext.Create;

socket := context.Socket( stDealer );
socket.connect( address );

// 创建轮询器。第二个参数可以为nil,此时轮询器会创建自己的上下文。
poller := TZMQPoller.Create( false, context );

poller.onEvent := pollerEvent;

// 注册套接字。如果第三个参数为true,注册将阻塞直到套接字注册完毕。
poller.register( socket, [pePollIn], false );


监视套接字(仅在
v3.2
可用)

<!--lang: delphi-->

// 像这样定义一个回调
procedure TMyClass.MonitorCallback( event: TZMQEvent );
begin
// do something.
end;

// 注册这个回调
socket.RegisterMonitor( MonitorCallback, cZMQMonitorEventsAll );

// MonitorCallback将会在由RegisterMonitor创建的分离的线程中被调用。

// 你可以这么调用来反注册监视。
socket.DeRegisterMonitor;

示例

示例位于 zguide 
examples/Delphi
 目录.

变更

New poller class
poll function of TZMQPoller has a new optional parameter "pollCount".
Upgrade dll-s to v3.2.2 RC2
New monitoring logic implemented.
Default ZMQ version for the binding is now 3.2 ( can switch back to 2.2 by not defining 
zmq3
 in the
zmq.inc
 file )

作者

以下为项目的贡献人员:

Balazs Varga <bb.varga@gmail.com>
Stathis Gkotsis <stathis.gkotsis@gmail.com>
Stephane Carre <scarre.lu@gmail.com>

版权

遵循 GNU Lesser General Public License (LGPL) 条款将被授权自由使用此软件。细节请参看包含在发行内容中的文件
COPYING.LESSER
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  zeromq