关于delphi:ZMQ-指南第六章-ZMQ绑定Delphi版

39次阅读

共计 2914 个字符,预计需要花费 8 分钟才能阅读完成。

ZMQ 绑定 Delphi 版

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

概述

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

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

应用

你应该应用高层 API,那会节俭你大量工夫,而且附带成果是代码也将更容易浏览。

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

context := TZMQContext.Create;

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

socket := context.Socket(stRep);

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

// 连贯套接字
socket.connect(‘tcp://localhost:5555’);

API 中有很多中办法来发送音讯。你能够发送单份,或多份音讯,阻塞或非阻塞(v3 中称为 dontwait 不期待)模式。

// 阻塞模式(默认)发送一个字符串就像这么简略:
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;

接管音讯就像这么容易:

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

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

// 读取多段音讯
tsl := TStringList.Create;
mcount := socket.recv(tsl);
// 这将会增加多个音讯的局部到字符串列表,并返回接管的音讯数量。

CTRL+ C 的解决

这是个小技巧。在 Windows 中信号处理与 posix 零碎有所不同。阻塞调用不会接管到SIGINT,只会继续的阻塞。要克服这个问题,已装置的处理器终止了上下文,所以阻塞调用例如recvpoll,等等 … 将接管到ETERM。这仅在 Windows。

如果你将你的有限循环代码写为这样,你能够很洁净的终止。

while not context.Terminated do
try
socket.recv(msg);
except
// 解决异样,或者
context.Terminate;
end;

context.Free;

轮询

轮询能够工作在两种不同形式,让咱们称第一种为同步,第二种为异步形式。异步版本创立了一个线程,在其中做轮询。

  • 同步

// 创立上下文
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 模式,轮询器启动了一个新的线程,并在类和创立的线程之间创立了一对套接字连贯。所以这个轮询器的实现不是线程平安的,不要在不同线程中去注册、反注册套接字。

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 可用)

// 像这样定义一个回调
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 now3.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

正文完
 0