以下以 Delphi 语言为例子,描述在应用中将如何使用该客户端。编写该例子的程序之前,已经先将 %APUSIC_MQ_HOME%\client\win32appclient 目录中的 AMQClientWin32SpecDLL.dll 和 MQCClientlib.dll 两个文件拷贝到 Delphi 创建的工程的目录中。
添加外部函数定义
必须先在 Delphi 语言中对即将调用到的DLL中的函数作出定义。例如:
function AMQCreateConnection4(host:pchar; port:integer; user:pchar; password:pchar; connHandle:pinteger):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQCreateSession(connectionHandle:integer; transacted:integer; acknowledgeMode:integer; sessionHandle_out:pinteger):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQCloseConnection(connectionHandle:integer):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQCreateTopic(sessionHandle:integer; topicName:pchar; topicHandle_out:pinteger):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQCreateQueue(sessionHandle:integer; queueName:pchar; queueHandle_out:pinteger):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQCreateProducer(sessionHandle:integer; destinationHandle:integer; messageProducerHandle_out:pinteger):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQCreateTextMessage2(sessionHandle:integer; text:pchar; textMessageHandle_out:pinteger):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQSetMessageBooleanProperty(messageHandle:integer; name:pchar; value:integer):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQSetMessageStringProperty(messageHandle:integer; name:pchar; value:pchar):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQSendMessage1(messageProducerHandle:integer; messageHandle:integer):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQSendMessage3(messageProducerHandle:integer; destinationHandle:integer; messageHandle:integer):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQGetMessageText(textMessageHandle:integer; text_out:ppchar):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQGetMessageStringProperty(messageHandle:integer; name:pchar; property_out:ppchar):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQSetMessageText(textMessageHandle:integer; text:pchar):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQCloseMessageProducer(messageProducerHandle:integer):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQCloseSession(sessionHandle:integer):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQClearMessageProperties(messageHandle:integer):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQClearMessageBody(messageHandle:integer):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQCreateConsumer1(sessionHandle:integer; destinationHandle:integer; messageConsumerHandle_out:pinteger):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQCreateConsumer2(sessionHandle:integer; destinationHandle:integer; messageSelector:pchar; messageConsumerHandle_out:pinteger):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQCloseMessageConsumer(messageConsumerHandle:integer):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQReceiveMessage1(messageConsumerHandle:integer; messageHandle_out:pinteger):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQReceiveMessage2(messageConsumerHandle:integer; timeout:int64; messageHandle_out:pinteger):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQIsTextMessage(messageHandle:integer; isTextMessage_out:pinteger):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQStartConnection(connectionHandle:integer):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQGetMessageID(messageHandle:integer; messageID_out:ppchar):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll'; function AMQSetMessageReplyTo(messageHandle:integer; destinationHandle:integer):pchar;stdcall; external 'AMQClientWin32SpecDLL.dll';
消息发送端示例程序
以下的程序示例了如何使用 DLL 中的函数发送消息到 AMQ 服务器。
//检查函数调用结果的函数
procedure check(ret:pchar);
begin
if ret <> NIL then
begin
ShowMessage(ret);
halt(0);
end;
end;
procedure TAMQSampleForm.SendButtonClick(Sender: TObject);
var
//声明用于保存创建出来的资源的句柄
session : Integer;
queue : Integer;
replyQueue : Integer;
topic : Integer;
producer : Integer;
textMessage : Integer;
text : pchar;
conn : Integer;
msgID : pchar;
begin
//创建一个到服务器的连接,一个到服务器的连接可以在多个线程和多个Session中复用。
check(AMQCreateConnection4(host, port, user, password, @conn));
//创建一个Session,用于和服务器会话,进行消息的发送和接收
check(AMQCreateSession(conn, 0, 1, @session));
//创建一个testQueue队列的句柄
check(AMQCreateQueue(session, 'testQueue', @queue));
//创建一个testTopic主题的句柄,演示如何创建主题,但是这里没有使用
//该创建出来的句柄
check(AMQCreateTopic(session, 'testTopic', @topic));
//创建一个消息生产者,用于发送消息到 testQueue队列
check(AMQCreateProducer(session, queue, @producer));
text := pchar(sendedTextMemo.Text);
//用text的值创建一个TextMessage
check(AMQCreateTextMessage2(session, text, @textMessage));
//打开消息的跟踪消息传递时的消息路由路径的功能
check(AMQSetMessageBooleanProperty(textMessage, 'JMSXDebugRouting', 1));
//演示如何设置一个消息的String属性
check(AMQSetMessageStringProperty(textMessage, 'SampleStringPropertyKey', 'SampleStringPropertyValue'));
//演示如何重新设置一个TextMessage的文本内容
check(AMQSetMessageText(textMessage, text));
//将消息通过生产者发送出去
check(AMQSendMessage3(producer, queue, textMessage));
//演示得到消息的消息ID,要发送消息之后才能得到。
check(AMQGetMessageID(textMessage, @msgID));
//关闭消息生产者
AMQCloseMessageProducer(producer);
//关闭Session
AMQCloseSession(session);
//关闭连接
AMQCloseConnection(conn);
end;
消息接收端示例程序
以下的程序示例了如何使用 DLL 中的函数从 AMQ 服务器中接收消息。
//检查函数调用结果的函数
procedure check(ret:pchar);
begin
if ret <> NIL then
begin
ShowMessage(ret);
halt(0);
end;
end;
procedure TReceiveSampleForm.receiveButtonClick(Sender: TObject);
var
//声明用于保存创建出来的资源的句柄
session : Integer;
queue : Integer;
consumer : Integer;
textMessage : Integer;
isTextMessage : Integer;
text : pchar;
msgID : pchar;
routingTract : pchar;
replyQueue : Integer;
producer : Integer;
conn : Integer;
begin
//创建一个到服务器的连接,一个到服务器的连接可以在多个线程和多个Session中复用。
check(AMQCreateConnection4(host, port, user, password, @conn));
//创建一个Session,用于和服务器会话,进行消息的发送和接收
check(AMQCreateSession(conn, 0, 1, @session));
//创建一个testQueue队列的句柄
check(AMQCreateQueue(session, 'testQueue', @queue));
//创建一个消息消费者,用于从testQueue队列接收消息
check(AMQCreateConsumer1(session, queue, @consumer));
//启动连接,准备好接收消息,可以开始接收了
check(AMQStartConnection(conn));
//接收一个消息到textMessage的句柄中
check(AMQReceiveMessage1(consumer, @textMessage));
//判断该接收到的消息是否是 TextMessage 类型
check(AMQIsTextMessage(textMessage, @isTextMessage));
if isTextMessage = 1 then
begin
//取得该TextMessage中的内容
check(AMQGetMessageText(textMessage, @text));
//取得该TextMessage的消息传递时的路由路径
check(AMQGetMessageStringProperty(textMessage, 'JMSXRoutingTrack', @routingTract));
receivedMsgMemo.Lines.Add('消息内容为:');
receivedMsgMemo.Lines.Add('');
receivedMsgMemo.Lines.Add(text);
receivedMsgMemo.Lines.Add('');
receivedMsgMemo.Lines.Add('消息传递时的消息路由路径为:');
receivedMsgMemo.Lines.Add(routingTract);
//演示得到消息的回执消息的回复目的地
check(AMQGetMessageReplyTo(textMessage, @replyQueue));
//演示得到消息的ID
check(AMQGetMessageID(textMessage, @msgID));
//创建一个消息生产者,用于发送回执消息
check(AMQCreateProducer(session, replyQueue, @producer));
check(AMQCreateTextMessage2(session, 'receive ok', @textMessage));
//设置回执消息的关联消息ID,消息发送端根据关联消息ID来收取回执消息
check(AMQSetMessageCorrelationID(textMessage, msgID));
//发送回执消息
check(AMQSendMessage3(producer, replyQueue, textMessage));
//关闭消息生产者
AMQCloseMessageProducer(producer);
end;
//关闭消息消费者
AMQCloseMessageConsumer(consumer);
//关闭 Session
AMQCloseSession(session);
//关闭连接
AMQCloseConnection(conn);
end;