mirror of
https://github.com/danieleteti/delphimvcframework.git
synced 2024-11-16 00:05:53 +01:00
Support 1.1 beta
This commit is contained in:
parent
76d2d38432
commit
5ce5edb341
316
StompClient.pas
316
StompClient.pas
@ -1,6 +1,6 @@
|
||||
// Stomp Client for Embarcadero Delphi & FreePascal
|
||||
// Tested With ApacheMQ 5.2/5.3, Apache Apollo 1.2, RabbitMQ
|
||||
// Copyright (c) 2009-2015 Daniele Teti
|
||||
// Copyright (c) 2009-2016 Daniele Teti
|
||||
//
|
||||
// Contributors:
|
||||
// Daniel Gaspary: dgaspary@gmail.com
|
||||
@ -28,6 +28,7 @@ interface
|
||||
uses
|
||||
StompTypes,
|
||||
SysUtils,
|
||||
DateUtils,
|
||||
|
||||
{$IFNDEF USESYNAPSE}
|
||||
IdTCPClient,
|
||||
@ -46,6 +47,7 @@ type
|
||||
{ TStompClient }
|
||||
|
||||
TSenderFrameEvent = procedure(AFrame: IStompFrame) of object;
|
||||
THeartBeatThread = class;
|
||||
|
||||
TStompClient = class(TInterfacedObject, IStompClient)
|
||||
private
|
||||
@ -76,6 +78,13 @@ type
|
||||
FClientID: string;
|
||||
FAcceptVersion: TStompAcceptProtocol;
|
||||
FConnectionTimeout: UInt32;
|
||||
FOutgoingHeartBeats: Int64;
|
||||
FIncomingHeartBeats: Int64;
|
||||
FLock: TObject;
|
||||
FHeartBeatThread: THeartBeatThread;
|
||||
FServerIncomingHeartBeats: Int64;
|
||||
FServerOutgoingHeartBeats: Int64;
|
||||
procedure ParseHeartBeat(Headers: IStompHeaders);
|
||||
procedure SetReceiptTimeout(const Value: Integer);
|
||||
procedure SetConnectionTimeout(const Value: UInt32);
|
||||
|
||||
@ -91,7 +100,9 @@ type
|
||||
procedure MergeHeaders(var AFrame: IStompFrame;
|
||||
var AHeaders: IStompHeaders);
|
||||
procedure SendFrame(AFrame: IStompFrame);
|
||||
procedure SendHeartBeat;
|
||||
function FormatErrorFrame(const AErrorFrame: IStompFrame): string;
|
||||
function ServerSupportsHeartBeat: boolean;
|
||||
public
|
||||
function SetPassword(const Value: string): IStompClient;
|
||||
function SetUserName(const Value: string): IStompClient;
|
||||
@ -103,7 +114,7 @@ type
|
||||
procedure Connect(Host: string = '127.0.0.1';
|
||||
Port: Integer = DEFAULT_STOMP_PORT; ClientID: string = '';
|
||||
AcceptVersion: TStompAcceptProtocol = TStompAcceptProtocol.
|
||||
STOMP_Version_1_0);
|
||||
Ver_1_0);
|
||||
procedure Disconnect;
|
||||
procedure Subscribe(QueueOrTopicName: string;
|
||||
Ack: TAckMode = TAckMode.amAuto; Headers: IStompHeaders = nil);
|
||||
@ -125,8 +136,9 @@ type
|
||||
class function CreateAndConnect(Host: string = '127.0.0.1';
|
||||
Port: Integer = DEFAULT_STOMP_PORT; ClientID: string = '';
|
||||
AcceptVersion: TStompAcceptProtocol = TStompAcceptProtocol.
|
||||
STOMP_Version_1_0): IStompClient; overload; virtual;
|
||||
Ver_1_0): IStompClient; overload; virtual;
|
||||
destructor Destroy; override;
|
||||
procedure SetHeartBeat(const OutgoingHeartBeats, IncomingHeartBeats: Int64);
|
||||
function Clone: IStompClient;
|
||||
function Connected: boolean;
|
||||
function SetReceiveTimeout(const AMilliSeconds: Cardinal): IStompClient;
|
||||
@ -145,20 +157,34 @@ type
|
||||
write FOnAfterSendFrame;
|
||||
end;
|
||||
|
||||
THeartBeatThread = class(TThread)
|
||||
private
|
||||
FStompClient: TStompClient;
|
||||
FLock: TObject;
|
||||
FOutgoingHeatBeatTimeout: Int64;
|
||||
protected
|
||||
procedure Execute; override;
|
||||
public
|
||||
constructor Create(StompClient: TStompClient; Lock: TObject;
|
||||
OutgoingHeatBeatTimeout: Int64); virtual;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{$IFDEF FPC}
|
||||
|
||||
|
||||
const
|
||||
CHAR0 = #0;
|
||||
|
||||
{$ELSE}
|
||||
|
||||
|
||||
uses
|
||||
// Windows, // Remove windows unit for compiling on ios
|
||||
IdGlobal,
|
||||
IdGlobalProtocols,
|
||||
Character;
|
||||
Character, Winapi.Windows;
|
||||
|
||||
{$ENDIF}
|
||||
{ TStompClient }
|
||||
@ -170,8 +196,8 @@ begin
|
||||
if FTransactions.IndexOf(TransactionIdentifier) > -1 then
|
||||
begin
|
||||
Frame := TStompFrame.Create;
|
||||
Frame.SetCommand('ABORT');
|
||||
Frame.GetHeaders.Add('transaction', TransactionIdentifier);
|
||||
Frame.Command := 'ABORT';
|
||||
Frame.Headers.Add('transaction', TransactionIdentifier);
|
||||
SendFrame(Frame);
|
||||
FInTransaction := False;
|
||||
FTransactions.Delete(FTransactions.IndexOf(TransactionIdentifier));
|
||||
@ -188,10 +214,10 @@ var
|
||||
Frame: IStompFrame;
|
||||
begin
|
||||
Frame := TStompFrame.Create;
|
||||
Frame.SetCommand('ACK');
|
||||
Frame.GetHeaders.Add(TStompHeaders.MESSAGE_ID, MessageID);
|
||||
Frame.Command := 'ACK';
|
||||
Frame.Headers.Add(TStompHeaders.MESSAGE_ID, MessageID);
|
||||
if TransactionIdentifier <> '' then
|
||||
Frame.GetHeaders.Add('transaction', TransactionIdentifier);
|
||||
Frame.Headers.Add('transaction', TransactionIdentifier);
|
||||
SendFrame(Frame);
|
||||
end;
|
||||
|
||||
@ -202,8 +228,8 @@ begin
|
||||
if FTransactions.IndexOf(TransactionIdentifier) = -1 then
|
||||
begin
|
||||
Frame := TStompFrame.Create;
|
||||
Frame.SetCommand('BEGIN');
|
||||
Frame.GetHeaders.Add('transaction', TransactionIdentifier);
|
||||
Frame.Command := 'BEGIN';
|
||||
Frame.Headers.Add('transaction', TransactionIdentifier);
|
||||
SendFrame(Frame);
|
||||
// CheckReceipt(Frame);
|
||||
FInTransaction := True;
|
||||
@ -222,7 +248,7 @@ end;
|
||||
// if FEnableReceipts then
|
||||
// begin
|
||||
// ReceiptID := inttostr(GetTickCount);
|
||||
// Frame.GetHeaders.Add('receipt', ReceiptID);
|
||||
// Frame.Headers.Add('receipt', ReceiptID);
|
||||
// SendFrame(Frame);
|
||||
// Receipt(ReceiptID);
|
||||
// end
|
||||
@ -246,8 +272,8 @@ begin
|
||||
if FTransactions.IndexOf(TransactionIdentifier) > -1 then
|
||||
begin
|
||||
Frame := TStompFrame.Create;
|
||||
Frame.SetCommand('COMMIT');
|
||||
Frame.GetHeaders.Add('transaction', TransactionIdentifier);
|
||||
Frame.Command := 'COMMIT';
|
||||
Frame.Headers.Add('transaction', TransactionIdentifier);
|
||||
SendFrame(Frame);
|
||||
FInTransaction := False;
|
||||
FTransactions.Delete(FTransactions.IndexOf(TransactionIdentifier));
|
||||
@ -262,6 +288,7 @@ procedure TStompClient.Connect(Host: string; Port: Integer; ClientID: string;
|
||||
AcceptVersion: TStompAcceptProtocol);
|
||||
var
|
||||
Frame: IStompFrame;
|
||||
lHeartBeat: string;
|
||||
begin
|
||||
FHost := Host;
|
||||
FPort := Port;
|
||||
@ -283,34 +310,48 @@ begin
|
||||
|
||||
{$ENDIF}
|
||||
Frame := TStompFrame.Create;
|
||||
Frame.SetCommand('CONNECT');
|
||||
Frame.Command := 'CONNECT';
|
||||
|
||||
FClientAcceptProtocolVersion := AcceptVersion;
|
||||
if TStompAcceptProtocol.STOMP_Version_1_1 in [FClientAcceptProtocolVersion]
|
||||
if TStompAcceptProtocol.Ver_1_1 in [FClientAcceptProtocolVersion]
|
||||
then
|
||||
begin
|
||||
Frame.GetHeaders.Add('heart-beat', '0,1000'); // stomp 1.1
|
||||
Frame.GetHeaders.Add('accept-version', '1.1'); // stomp 1.1
|
||||
Frame.Headers.Add('accept-version', '1.1'); // stomp 1.1
|
||||
lHeartBeat := Format('%d,%d', [FOutgoingHeartBeats, FIncomingHeartBeats]);
|
||||
Frame.Headers.Add('heart-beat', lHeartBeat); // stomp 1.1
|
||||
end
|
||||
else
|
||||
begin
|
||||
Frame.Headers.Add('accept-version', '1.0'); // stomp 1.0
|
||||
end;
|
||||
|
||||
Frame.GetHeaders.Add('login', FUserName).Add('passcode', FPassword);
|
||||
Frame.Headers.Add('login', FUserName).Add('passcode', FPassword);
|
||||
FClientID := ClientID;
|
||||
if ClientID <> '' then
|
||||
begin
|
||||
Frame.GetHeaders.Add('client-id', ClientID);
|
||||
Frame.Headers.Add('client-id', ClientID);
|
||||
end;
|
||||
SendFrame(Frame);
|
||||
Frame := nil;
|
||||
while Frame = nil do
|
||||
Frame := Receive;
|
||||
if Frame.GetCommand = 'ERROR' then
|
||||
if Frame.Command = 'ERROR' then
|
||||
raise EStomp.Create(FormatErrorFrame(Frame));
|
||||
if Frame.GetCommand = 'CONNECTED' then
|
||||
if Frame.Command = 'CONNECTED' then
|
||||
begin
|
||||
FSession := Frame.GetHeaders.Value('session');
|
||||
FServerProtocolVersion := Frame.GetHeaders.Value('version'); // stomp 1.1
|
||||
FServer := Frame.GetHeaders.Value('server'); // stomp 1.1
|
||||
FSession := Frame.Headers.Value('session');
|
||||
FServerProtocolVersion := Frame.Headers.Value('version'); // stomp 1.1
|
||||
FServer := Frame.Headers.Value('server'); // stomp 1.1
|
||||
ParseHeartBeat(Frame.Headers);
|
||||
end;
|
||||
|
||||
// Let's start the hearbeat thread
|
||||
if ServerSupportsHeartBeat then
|
||||
begin
|
||||
FHeartBeatThread := THeartBeatThread.Create(Self, FLock, FServerOutgoingHeartBeats);
|
||||
FHeartBeatThread.Start;
|
||||
end;
|
||||
|
||||
{ todo: 'Call event?' }
|
||||
except
|
||||
on E: Exception do
|
||||
@ -342,6 +383,7 @@ end;
|
||||
constructor TStompClient.Create;
|
||||
begin
|
||||
inherited;
|
||||
FLock := TObject.Create;
|
||||
FInTransaction := False;
|
||||
FSession := '';
|
||||
FUserName := 'guest';
|
||||
@ -350,6 +392,8 @@ begin
|
||||
FTimeout := 200;
|
||||
FReceiptTimeout := FTimeout;
|
||||
FConnectionTimeout := 1000 * 10; // 10secs
|
||||
FIncomingHeartBeats := 10000; // 10secs
|
||||
FOutgoingHeartBeats := 0; // disabled
|
||||
end;
|
||||
|
||||
procedure TStompClient.DeInit;
|
||||
@ -369,6 +413,7 @@ destructor TStompClient.Destroy;
|
||||
begin
|
||||
Disconnect;
|
||||
DeInit;
|
||||
FLock.Free;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
@ -378,8 +423,16 @@ var
|
||||
begin
|
||||
if Connected then
|
||||
begin
|
||||
if ServerSupportsHeartBeat then
|
||||
begin
|
||||
Assert(Assigned(FHeartBeatThread), 'HeartBeat thread not created');
|
||||
FHeartBeatThread.Terminate;
|
||||
FHeartBeatThread.WaitFor;
|
||||
FHeartBeatThread.Free;
|
||||
end;
|
||||
|
||||
Frame := TStompFrame.Create;
|
||||
Frame.SetCommand('DISCONNECT');
|
||||
Frame.Command := 'DISCONNECT';
|
||||
SendFrame(Frame);
|
||||
|
||||
{$IFDEF USESYNAPSE}
|
||||
@ -396,10 +449,10 @@ end;
|
||||
|
||||
function TStompClient.FormatErrorFrame(const AErrorFrame: IStompFrame): string;
|
||||
begin
|
||||
if AErrorFrame.GetCommand <> 'ERROR' then
|
||||
if AErrorFrame.Command <> 'ERROR' then
|
||||
raise EStomp.Create('Not an ERROR frame');
|
||||
Result := AErrorFrame.GetHeaders.Value('message') + ': ' +
|
||||
AErrorFrame.GetBody;
|
||||
Result := AErrorFrame.Headers.Value('message') + ': ' +
|
||||
AErrorFrame.Body;
|
||||
end;
|
||||
|
||||
function TStompClient.GetProtocolVersion: string;
|
||||
@ -435,6 +488,7 @@ end;
|
||||
|
||||
{$IFDEF USESYNAPSE}
|
||||
|
||||
|
||||
procedure TStompClient.SynapseSocketCallBack(Sender: TObject;
|
||||
Reason: THookSocketReason; const Value: string);
|
||||
begin
|
||||
@ -448,6 +502,7 @@ end;
|
||||
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
procedure TStompClient.MergeHeaders(var AFrame: IStompFrame;
|
||||
var AHeaders: IStompHeaders);
|
||||
var
|
||||
@ -459,12 +514,12 @@ begin
|
||||
for i := 0 to AHeaders.Count - 1 do
|
||||
begin
|
||||
h := AHeaders.GetAt(i);
|
||||
AFrame.GetHeaders.Add(h.Key, h.Value);
|
||||
AFrame.Headers.Add(h.Key, h.Value);
|
||||
end;
|
||||
|
||||
// If the frame has some content, then set the length of that content.
|
||||
if (AFrame.ContentLength > 0) then
|
||||
AFrame.GetHeaders.Add('content-length', intToStr(AFrame.ContentLength));
|
||||
AFrame.Headers.Add('content-length', intToStr(AFrame.ContentLength));
|
||||
end;
|
||||
|
||||
procedure TStompClient.Nack(const MessageID, TransactionIdentifier: string);
|
||||
@ -472,22 +527,39 @@ var
|
||||
Frame: IStompFrame;
|
||||
begin
|
||||
Frame := TStompFrame.Create;
|
||||
Frame.SetCommand('NACK');
|
||||
Frame.GetHeaders.Add('message-id', MessageID);
|
||||
Frame.Command := 'NACK';
|
||||
Frame.Headers.Add('message-id', MessageID);
|
||||
if TransactionIdentifier <> '' then
|
||||
Frame.GetHeaders.Add('transaction', TransactionIdentifier);
|
||||
Frame.Headers.Add('transaction', TransactionIdentifier);
|
||||
SendFrame(Frame);
|
||||
end;
|
||||
|
||||
procedure TStompClient.ParseHeartBeat(Headers: IStompHeaders);
|
||||
var
|
||||
lValue: string;
|
||||
lIntValue: string;
|
||||
begin
|
||||
FServerOutgoingHeartBeats := 0;
|
||||
FServerIncomingHeartBeats := 0;
|
||||
//WARNING!! server heart beat is reversed
|
||||
lValue := Headers.Value('heart-beat');
|
||||
if Trim(lValue) <> '' then
|
||||
begin
|
||||
lIntValue := Fetch(lValue, ',');
|
||||
FServerIncomingHeartBeats := StrToInt(lIntValue);
|
||||
FServerOutgoingHeartBeats := StrToInt(lValue);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TStompClient.Receipt(const ReceiptID: string);
|
||||
var
|
||||
Frame: IStompFrame;
|
||||
begin
|
||||
if Receive(Frame, FReceiptTimeout) then
|
||||
begin
|
||||
if Frame.GetCommand <> 'RECEIPT' then
|
||||
if Frame.Command <> 'RECEIPT' then
|
||||
raise EStomp.Create('Receipt command error');
|
||||
if Frame.GetHeaders.Value('receipt-id') <> ReceiptID then
|
||||
if Frame.Headers.Value('receipt-id') <> ReceiptID then
|
||||
raise EStomp.Create('Receipt receipt-id error');
|
||||
end;
|
||||
end;
|
||||
@ -559,12 +631,13 @@ function TStompClient.Receive(ATimeout: Integer): IStompFrame;
|
||||
{$ELSE}
|
||||
function InternalReceiveINDY(ATimeout: Integer): IStompFrame;
|
||||
var
|
||||
s: string;
|
||||
lLine: string;
|
||||
lSBuilder: TStringBuilder;
|
||||
Headers: TIdHeaderList;
|
||||
ContentLength: Integer;
|
||||
Charset: string;
|
||||
|
||||
lHeartBeat: boolean;
|
||||
lTimestampFirstReadLn: TDateTime;
|
||||
{$IF CompilerVersion < 24}
|
||||
Encoding: TIdTextEncoding;
|
||||
FreeEncoding: boolean;
|
||||
@ -580,32 +653,54 @@ function TStompClient.Receive(ATimeout: Integer): IStompFrame;
|
||||
{$IF CompilerVersion < 24}TIdTextEncoding.UTF8{$ELSE}IndyTextEncoding_UTF8{$ENDIF};
|
||||
|
||||
try
|
||||
lTimestampFirstReadLn := Now;
|
||||
// read command line
|
||||
// repeat
|
||||
s := FTCP.Socket.ReadLn(LF, ATimeout, -1,
|
||||
FTCP.Socket.DefStringEncoding);
|
||||
// until s <> '';
|
||||
if s = '' then
|
||||
while True do
|
||||
begin
|
||||
lLine := FTCP.Socket.ReadLn(LF, ATimeout, -1,
|
||||
FTCP.Socket.DefStringEncoding);
|
||||
|
||||
if FTCP.Socket.ReadLnTimedout then
|
||||
Break;
|
||||
|
||||
lHeartBeat := lLine = ''; // here is not timeout because of the previous line
|
||||
if lHeartBeat then
|
||||
WinApi.Windows.Beep(1500,200);
|
||||
|
||||
if FServerProtocolVersion = '1.1' then // 1.1 supports heart-beats
|
||||
begin
|
||||
if (not lHeartBeat) or (lLine <> '') then
|
||||
Break;
|
||||
if MilliSecondsBetween(lTimestampFirstReadLn, Now) >= ATimeout then
|
||||
Break;
|
||||
end
|
||||
else
|
||||
Break; // 1.0
|
||||
end;
|
||||
|
||||
if lLine = '' then
|
||||
Exit(nil);
|
||||
lSBuilder.Append(s + LF);
|
||||
lSBuilder.Append(lLine + LF);
|
||||
|
||||
// read headers
|
||||
Headers := TIdHeaderList.Create(QuotePlain);
|
||||
|
||||
try
|
||||
repeat
|
||||
s := FTCP.Socket.ReadLn;
|
||||
lSBuilder.Append(s + LF);
|
||||
if s = '' then
|
||||
lLine := FTCP.Socket.ReadLn;
|
||||
lSBuilder.Append(lLine + LF);
|
||||
if lLine = '' then
|
||||
Break;
|
||||
Headers.Add(s);
|
||||
// in case of duplicated header, only the first is considered
|
||||
// https://stomp.github.io/stomp-specification-1.1.html#Repeated_Header_Entries
|
||||
if Headers.IndexOfName(Fetch(lLine, ':', False, False)) = -1 then
|
||||
Headers.Add(lLine);
|
||||
until False;
|
||||
|
||||
// read body
|
||||
//
|
||||
// NOTE: non-text data really should be read as a Stream instead of a String!!!
|
||||
//
|
||||
|
||||
if IsHeaderMediaType(Headers.Values['content-type'], 'text') then
|
||||
begin
|
||||
Charset := Headers.Params['content-type', 'charset'];
|
||||
@ -633,8 +728,8 @@ function TStompClient.Receive(ATimeout: Integer): IStompFrame;
|
||||
ContentLength := IndyStrToInt(Headers.Values['content-length']);
|
||||
if ContentLength > 0 then
|
||||
begin
|
||||
s := FTCP.Socket.ReadString(ContentLength, Encoding);
|
||||
lSBuilder.Append(s);
|
||||
lLine := FTCP.Socket.ReadString(ContentLength, Encoding);
|
||||
lSBuilder.Append(lLine);
|
||||
end;
|
||||
// frame must still be terminated by a null
|
||||
FTCP.Socket.ReadLn(#0 + LF);
|
||||
@ -643,8 +738,8 @@ function TStompClient.Receive(ATimeout: Integer): IStompFrame;
|
||||
|
||||
begin
|
||||
// no length specified, body terminated by frame terminating null
|
||||
s := FTCP.Socket.ReadLn(#0 + LF, Encoding);
|
||||
lSBuilder.Append(s);
|
||||
lLine := FTCP.Socket.ReadLn(#0 + LF, Encoding);
|
||||
lSBuilder.Append(lLine);
|
||||
|
||||
end;
|
||||
lSBuilder.Append(#0);
|
||||
@ -667,7 +762,7 @@ function TStompClient.Receive(ATimeout: Integer): IStompFrame;
|
||||
end;
|
||||
end;
|
||||
Result := StompUtils.CreateFrame(lSBuilder.toString);
|
||||
if Result.GetCommand = 'ERROR' then
|
||||
if Result.Command = 'ERROR' then
|
||||
raise EStomp.Create(FormatErrorFrame(Result));
|
||||
finally
|
||||
lSBuilder.Free;
|
||||
@ -676,6 +771,7 @@ function TStompClient.Receive(ATimeout: Integer): IStompFrame;
|
||||
|
||||
{$ENDIF}
|
||||
|
||||
|
||||
begin
|
||||
|
||||
{$IFDEF USESYNAPSE}
|
||||
@ -698,9 +794,9 @@ var
|
||||
Frame: IStompFrame;
|
||||
begin
|
||||
Frame := TStompFrame.Create;
|
||||
Frame.SetCommand('SEND');
|
||||
Frame.GetHeaders.Add('destination', QueueOrTopicName);
|
||||
Frame.SetBody(TextMessage);
|
||||
Frame.Command := 'SEND';
|
||||
Frame.Headers.Add('destination', QueueOrTopicName);
|
||||
Frame.Body := TextMessage;
|
||||
MergeHeaders(Frame, Headers);
|
||||
SendFrame(Frame);
|
||||
end;
|
||||
@ -711,39 +807,69 @@ var
|
||||
Frame: IStompFrame;
|
||||
begin
|
||||
Frame := TStompFrame.Create;
|
||||
Frame.SetCommand('SEND');
|
||||
Frame.GetHeaders.Add('destination', QueueOrTopicName);
|
||||
Frame.GetHeaders.Add('transaction', TransactionIdentifier);
|
||||
Frame.SetBody(TextMessage);
|
||||
Frame.Command := 'SEND';
|
||||
Frame.Headers.Add('destination', QueueOrTopicName);
|
||||
Frame.Headers.Add('transaction', TransactionIdentifier);
|
||||
Frame.Body := TextMessage;
|
||||
MergeHeaders(Frame, Headers);
|
||||
SendFrame(Frame);
|
||||
end;
|
||||
|
||||
procedure TStompClient.SendFrame(AFrame: IStompFrame);
|
||||
begin
|
||||
|
||||
TMonitor.Enter(FLock);
|
||||
try
|
||||
{$IFDEF USESYNAPSE}
|
||||
if Assigned(FOnBeforeSendFrame) then
|
||||
FOnBeforeSendFrame(AFrame);
|
||||
FSynapseTCP.SendString(AFrame.output);
|
||||
if Assigned(FOnAfterSendFrame) then
|
||||
FOnAfterSendFrame(AFrame);
|
||||
if Assigned(FOnBeforeSendFrame) then
|
||||
FOnBeforeSendFrame(AFrame);
|
||||
FSynapseTCP.SendString(AFrame.output);
|
||||
if Assigned(FOnAfterSendFrame) then
|
||||
FOnAfterSendFrame(AFrame);
|
||||
|
||||
{$ELSE}
|
||||
// FTCP.IOHandler.write(TEncoding.ASCII.GetBytes(AFrame.output));
|
||||
if Assigned(FOnBeforeSendFrame) then
|
||||
FOnBeforeSendFrame(AFrame);
|
||||
// FTCP.IOHandler.write(TEncoding.ASCII.GetBytes(AFrame.output));
|
||||
if Assigned(FOnBeforeSendFrame) then
|
||||
FOnBeforeSendFrame(AFrame);
|
||||
|
||||
{$IF CompilerVersion < 25}
|
||||
FTCP.IOHandler.write(TEncoding.UTF8.GetBytes(AFrame.output));
|
||||
FTCP.IOHandler.write(TEncoding.UTF8.GetBytes(AFrame.output));
|
||||
{$IFEND}
|
||||
{$IF CompilerVersion >= 25}
|
||||
FTCP.IOHandler.write(IndyTextEncoding_UTF8.GetBytes(AFrame.output));
|
||||
FTCP.IOHandler.write(IndyTextEncoding_UTF8.GetBytes(AFrame.output));
|
||||
{$IFEND}
|
||||
if Assigned(FOnAfterSendFrame) then
|
||||
FOnAfterSendFrame(AFrame);
|
||||
if Assigned(FOnAfterSendFrame) then
|
||||
FOnAfterSendFrame(AFrame);
|
||||
|
||||
{$ENDIF}
|
||||
finally
|
||||
TMonitor.Exit(FLock);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TStompClient.SendHeartBeat;
|
||||
begin
|
||||
TMonitor.Enter(FLock);
|
||||
try
|
||||
Winapi.Windows.Beep(600, 200);
|
||||
{$IFDEF USESYNAPSE}
|
||||
FSynapseTCP.SendString(LF);
|
||||
{$ELSE}
|
||||
{$IF CompilerVersion < 25}
|
||||
FTCP.IOHandler.write(TEncoding.UTF8.GetBytes(LF));
|
||||
{$IFEND}
|
||||
{$IF CompilerVersion >= 25}
|
||||
FTCP.IOHandler.write(IndyTextEncoding_UTF8.GetBytes(LF));
|
||||
{$IFEND}
|
||||
{$ENDIF}
|
||||
finally
|
||||
TMonitor.Exit(FLock);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function TStompClient.ServerSupportsHeartBeat: boolean;
|
||||
begin
|
||||
Result := (FServerProtocolVersion = '1.1') and (FServerOutgoingHeartBeats > 0)
|
||||
end;
|
||||
|
||||
procedure TStompClient.SetConnectionTimeout(const Value: UInt32);
|
||||
@ -751,6 +877,13 @@ begin
|
||||
FConnectionTimeout := Value;
|
||||
end;
|
||||
|
||||
procedure TStompClient.SetHeartBeat(const OutgoingHeartBeats,
|
||||
IncomingHeartBeats: Int64);
|
||||
begin
|
||||
FOutgoingHeartBeats := OutgoingHeartBeats;
|
||||
FIncomingHeartBeats := IncomingHeartBeats;
|
||||
end;
|
||||
|
||||
function TStompClient.SetPassword(const Value: string): IStompClient;
|
||||
begin
|
||||
FPassword := Value;
|
||||
@ -781,8 +914,8 @@ var
|
||||
Frame: IStompFrame;
|
||||
begin
|
||||
Frame := TStompFrame.Create;
|
||||
Frame.SetCommand('SUBSCRIBE');
|
||||
Frame.GetHeaders.Add('destination', QueueOrTopicName)
|
||||
Frame.Command := 'SUBSCRIBE';
|
||||
Frame.Headers.Add('destination', QueueOrTopicName)
|
||||
.Add('ack', StompUtils.AckModeToStr(Ack));
|
||||
if Headers <> nil then
|
||||
MergeHeaders(Frame, Headers);
|
||||
@ -794,9 +927,36 @@ var
|
||||
Frame: IStompFrame;
|
||||
begin
|
||||
Frame := TStompFrame.Create;
|
||||
Frame.SetCommand('UNSUBSCRIBE');
|
||||
Frame.GetHeaders.Add('destination', Queue);
|
||||
Frame.Command := 'UNSUBSCRIBE';
|
||||
Frame.Headers.Add('destination', Queue);
|
||||
SendFrame(Frame);
|
||||
end;
|
||||
|
||||
{ THeartBeatThread }
|
||||
|
||||
constructor THeartBeatThread.Create(StompClient: TStompClient; Lock: TObject;
|
||||
OutgoingHeatBeatTimeout: Int64);
|
||||
begin
|
||||
inherited Create(True);
|
||||
FStompClient := StompClient;
|
||||
FLock := Lock;
|
||||
FOutgoingHeatBeatTimeout := OutgoingHeatBeatTimeout;
|
||||
end;
|
||||
|
||||
procedure THeartBeatThread.Execute;
|
||||
var
|
||||
lStart: TDateTime;
|
||||
begin
|
||||
while not Terminated do
|
||||
begin
|
||||
lStart := Now;
|
||||
while (not Terminated) and (MilliSecondsBetween(Now, lStart) < FOutgoingHeatBeatTimeout) do
|
||||
begin
|
||||
Sleep(100);
|
||||
end;
|
||||
if not Terminated then
|
||||
FStompClient.SendHeartBeat;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
130
StompTypes.pas
130
StompTypes.pas
@ -1,6 +1,6 @@
|
||||
// Stomp Client for Embarcadero Delphi & FreePascal
|
||||
// Tested With ApacheMQ 5.2/5.3, Apache Apollo 1.2, RabbitMQ
|
||||
// Copyright (c) 2009-2015 Daniele Teti
|
||||
// Copyright (c) 2009-2016 Daniele Teti
|
||||
//
|
||||
// Contributors:
|
||||
// Daniel Gaspary: dgaspary@gmail.com
|
||||
@ -29,7 +29,7 @@ const
|
||||
type
|
||||
TAckMode = (amAuto, amClient, amClientIndividual { STOMP 1.1 } );
|
||||
|
||||
TStompAcceptProtocol = (STOMP_Version_1_0, STOMP_Version_1_1);
|
||||
TStompAcceptProtocol = (Ver_1_0, Ver_1_1);
|
||||
|
||||
EStomp = class(Exception)
|
||||
end;
|
||||
@ -66,6 +66,8 @@ type
|
||||
function MessageID: string;
|
||||
function ContentLength: Integer;
|
||||
function ReplyTo: string;
|
||||
property Headers: IStompHeaders read GetHeaders write SetHeaders;
|
||||
property Command: string read GetCommand write SetCommand;
|
||||
end;
|
||||
|
||||
IStompClient = interface
|
||||
@ -77,7 +79,7 @@ type
|
||||
procedure Receipt(const ReceiptID: string);
|
||||
procedure Connect(Host: string = '127.0.0.1'; Port: Integer = 61613;
|
||||
ClientID: string = '';
|
||||
AcceptVersion: TStompAcceptProtocol = STOMP_Version_1_0);
|
||||
AcceptVersion: TStompAcceptProtocol = Ver_1_0);
|
||||
function Clone: IStompClient;
|
||||
procedure Disconnect;
|
||||
procedure Subscribe(QueueOrTopicName: string; Ack: TAckMode = amAuto;
|
||||
@ -89,16 +91,17 @@ type
|
||||
TransactionIdentifier: string; Headers: IStompHeaders = nil); overload;
|
||||
procedure Ack(const MessageID: string;
|
||||
const TransactionIdentifier: string = '');
|
||||
{ STOMP 1.1 }
|
||||
{ ** STOMP 1.1 ** }
|
||||
procedure Nack(const MessageID: string;
|
||||
const TransactionIdentifier: string = '');
|
||||
procedure BeginTransaction(const TransactionIdentifier: string);
|
||||
procedure CommitTransaction(const TransactionIdentifier: string);
|
||||
procedure AbortTransaction(const TransactionIdentifier: string);
|
||||
/// ////////////
|
||||
{ ****************************************************************** }
|
||||
function SetPassword(const Value: string): IStompClient;
|
||||
function SetUserName(const Value: string): IStompClient;
|
||||
function SetReceiveTimeout(const AMilliSeconds: Cardinal): IStompClient;
|
||||
procedure SetHeartBeat(const OutgoingHeartBeats, IncomingHeartBeats: Int64);
|
||||
function Connected: Boolean;
|
||||
function GetProtocolVersion: string;
|
||||
function GetServer: string;
|
||||
@ -188,30 +191,29 @@ type
|
||||
IStompListener = interface
|
||||
['{CB3EB297-8616-408E-A0B2-7CCC11224DBC}']
|
||||
procedure StopListening;
|
||||
procedure StartListening;
|
||||
end;
|
||||
|
||||
IStompClientListener = interface
|
||||
['{C4C0D932-8994-43FB-9D32-A03FE86AEFE4}']
|
||||
procedure OnMessage(StompClient: IStompClient; StompFrame: IStompFrame;
|
||||
var StompListening: Boolean);
|
||||
procedure OnStopListen(StompClient: IStompClient);
|
||||
procedure OnMessage(MessageBody: string; var TerminateListener: Boolean);
|
||||
procedure OnListenerStopped(StompClient: IStompClient);
|
||||
end;
|
||||
|
||||
{ TODO -oDaniele -cGeneral : Use TThread by composition and not by inheritance }
|
||||
TStompClientListener = class(TThread, IStompListener)
|
||||
strict protected
|
||||
TStompClientListener = class(TInterfacedObject, IStompListener)
|
||||
strict private
|
||||
FReceiverThread: TThread;
|
||||
FTerminated: Boolean;
|
||||
private
|
||||
FStompClientListener: IStompClientListener;
|
||||
strict protected
|
||||
FStompClient: IStompClient;
|
||||
procedure Execute; override;
|
||||
|
||||
public
|
||||
constructor Create(StompClient: IStompClient;
|
||||
StompClientListener: IStompClientListener);
|
||||
constructor Create(const StompClient: IStompClient;
|
||||
const StompClientListener: IStompClientListener); virtual;
|
||||
destructor Destroy; override;
|
||||
procedure StartListening;
|
||||
procedure StopListening;
|
||||
function QueryInterface(const IID: TGUID; out Obj): HRESULT; stdcall;
|
||||
function _AddRef: Integer; stdcall;
|
||||
function _Release: Integer; stdcall;
|
||||
|
||||
end;
|
||||
|
||||
type
|
||||
@ -225,6 +227,16 @@ type
|
||||
class function TimestampAsDateTime(const HeaderValue: string): TDateTime;
|
||||
end;
|
||||
|
||||
TReceiverThread = class(TThread)
|
||||
private
|
||||
FStompClient: IStompClient;
|
||||
FStompClientListener: IStompClientListener;
|
||||
protected
|
||||
procedure Execute; override;
|
||||
public
|
||||
constructor Create(StompClient: IStompClient; StompClientListener: IStompClientListener);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@ -431,7 +443,7 @@ begin
|
||||
on e: Exception do
|
||||
begin
|
||||
Result.Free;
|
||||
raise EStomp.Create(e.message);
|
||||
raise EStomp.Create(e.Message);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -588,56 +600,72 @@ end;
|
||||
|
||||
{ TStompListener }
|
||||
|
||||
constructor TStompClientListener.Create(StompClient: IStompClient;
|
||||
StompClientListener: IStompClientListener);
|
||||
constructor TStompClientListener.Create(const StompClient: IStompClient;
|
||||
const StompClientListener: IStompClientListener);
|
||||
begin
|
||||
FStompClientListener := StompClientListener;
|
||||
FStompClient := StompClient;
|
||||
inherited Create(false);
|
||||
FTerminated := False;
|
||||
FReceiverThread := nil;
|
||||
inherited Create;
|
||||
end;
|
||||
|
||||
procedure TStompClientListener.Execute;
|
||||
var
|
||||
frame: IStompFrame;
|
||||
StopListen: Boolean;
|
||||
destructor TStompClientListener.Destroy;
|
||||
begin
|
||||
StopListen := false;
|
||||
while not terminated do
|
||||
begin
|
||||
if FStompClient.Receive(frame, 1000) then
|
||||
begin
|
||||
FStompClientListener.OnMessage(FStompClient, frame, StopListen);
|
||||
if StopListen then
|
||||
begin
|
||||
FStompClientListener.OnStopListen(FStompClient);
|
||||
if not terminated then
|
||||
StopListening;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
FTerminated := true;
|
||||
FReceiverThread.Free;
|
||||
inherited;
|
||||
end;
|
||||
|
||||
function TStompClientListener.QueryInterface(const IID: TGUID; out Obj)
|
||||
: HRESULT;
|
||||
procedure TStompClientListener.StartListening;
|
||||
begin
|
||||
Result := E_NOINTERFACE;
|
||||
if Assigned(FReceiverThread) then
|
||||
raise EStomp.Create('Already listening');
|
||||
FReceiverThread := TReceiverThread.Create(FStompClient, FStompClientListener);
|
||||
FReceiverThread.Start;
|
||||
end;
|
||||
|
||||
procedure TStompClientListener.StopListening;
|
||||
begin
|
||||
Terminate;
|
||||
// Free;
|
||||
// WaitFor;
|
||||
if not Assigned(FReceiverThread) then
|
||||
exit;
|
||||
FReceiverThread.Terminate;
|
||||
FReceiverThread.Free;
|
||||
FReceiverThread := nil;
|
||||
end;
|
||||
|
||||
function TStompClientListener._AddRef: Integer;
|
||||
{ TReceiverThread }
|
||||
|
||||
constructor TReceiverThread.Create(StompClient: IStompClient;
|
||||
StompClientListener: IStompClientListener);
|
||||
begin
|
||||
Result := -1;
|
||||
inherited Create(true);
|
||||
FStompClient := StompClient;
|
||||
FStompClientListener := StompClientListener;
|
||||
end;
|
||||
|
||||
function TStompClientListener._Release: Integer;
|
||||
procedure TReceiverThread.Execute;
|
||||
var
|
||||
LFrame: IStompFrame;
|
||||
LTerminateListener: Boolean;
|
||||
begin
|
||||
Result := -1;
|
||||
LTerminateListener := False;
|
||||
while (not Terminated) and (not LTerminateListener) do
|
||||
begin
|
||||
if FStompClient.Receive(LFrame, 1000) then
|
||||
begin
|
||||
TThread.Synchronize(nil,
|
||||
procedure
|
||||
begin
|
||||
FStompClientListener.OnMessage(LFrame.Body, LTerminateListener);
|
||||
end);
|
||||
end;
|
||||
end;
|
||||
TThread.Synchronize(nil,
|
||||
procedure
|
||||
begin
|
||||
FStompClientListener.OnListenerStopped(FStompClient);
|
||||
end);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{725AE3B6-F1CE-42B3-BA06-F919DCE3AB46}</ProjectGuid>
|
||||
<ProjectVersion>16.1</ProjectVersion>
|
||||
<ProjectVersion>18.1</ProjectVersion>
|
||||
<MainSource>ChatClient.dpr</MainSource>
|
||||
<Config Condition="'$(Config)'==''">Debug</Config>
|
||||
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
|
||||
@ -52,6 +52,7 @@
|
||||
<DCC_Platform>x86</DCC_Platform>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_Win32)'!=''">
|
||||
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
|
||||
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
|
||||
<Icon_MainIcon>ChatClient_Icon.ico</Icon_MainIcon>
|
||||
<DCC_Namespace>System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
|
||||
@ -59,6 +60,7 @@
|
||||
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_Win64)'!=''">
|
||||
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
|
||||
<Icon_MainIcon>ChatClient_Icon.ico</Icon_MainIcon>
|
||||
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
|
||||
</PropertyGroup>
|
||||
|
Binary file not shown.
@ -39,8 +39,8 @@ procedure TForm5.Button1Click(Sender: TObject);
|
||||
begin
|
||||
roomname := '/topic/' + Edit2.Text;
|
||||
stomp := TStompClient.Create;
|
||||
stomp.SetUserName('admin');
|
||||
stomp.SetPassword('password');
|
||||
// stomp.SetUserName('admin');
|
||||
// stomp.SetPassword('password');
|
||||
stomp.Connect(Edit1.Text);
|
||||
|
||||
//Setup for reading messages
|
||||
|
@ -63,6 +63,7 @@ uses
|
||||
|
||||
{$R *.dfm}
|
||||
|
||||
|
||||
procedure TForm1.ApplicationEvents1Idle(Sender: TObject; var Done: Boolean);
|
||||
begin
|
||||
ListBox1.Items.BeginUpdate;
|
||||
@ -117,7 +118,10 @@ end;
|
||||
procedure TForm1.Button5Click(Sender: TObject);
|
||||
begin
|
||||
LSTOMP.Subscribe(Edit1.Text, amAuto,
|
||||
StompUtils.NewHeaders.Add(TStompHeaders.NewDurableSubscriptionHeader('pippo')));
|
||||
StompUtils.Headers
|
||||
.Add(TStompHeaders.Persistent(true))
|
||||
.Add(TStompHeaders.Durable(true))
|
||||
);
|
||||
end;
|
||||
|
||||
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
|
||||
|
@ -11,6 +11,8 @@ object Form4: TForm4
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = []
|
||||
OldCreateOrder = False
|
||||
OnCreate = FormCreate
|
||||
OnDestroy = FormDestroy
|
||||
DesignSize = (
|
||||
527
|
||||
506)
|
||||
@ -19,17 +21,17 @@ object Form4: TForm4
|
||||
object Button1: TButton
|
||||
Left = 8
|
||||
Top = 8
|
||||
Width = 113
|
||||
Height = 25
|
||||
Width = 137
|
||||
Height = 42
|
||||
Caption = 'Start'
|
||||
TabOrder = 0
|
||||
OnClick = Button1Click
|
||||
end
|
||||
object Memo1: TMemo
|
||||
Left = 8
|
||||
Top = 39
|
||||
Top = 56
|
||||
Width = 511
|
||||
Height = 459
|
||||
Height = 442
|
||||
Anchors = [akLeft, akTop, akRight, akBottom]
|
||||
Font.Charset = ANSI_CHARSET
|
||||
Font.Color = clWindowText
|
||||
@ -39,4 +41,24 @@ object Form4: TForm4
|
||||
ParentFont = False
|
||||
TabOrder = 1
|
||||
end
|
||||
object Button2: TButton
|
||||
Left = 151
|
||||
Top = 8
|
||||
Width = 137
|
||||
Height = 42
|
||||
Caption = 'Stop'
|
||||
TabOrder = 2
|
||||
OnClick = Button2Click
|
||||
end
|
||||
object Button3: TButton
|
||||
Left = 392
|
||||
Top = 8
|
||||
Width = 127
|
||||
Height = 42
|
||||
Anchors = [akTop, akRight]
|
||||
Caption = 'Produce messages continuosly'
|
||||
TabOrder = 3
|
||||
WordWrap = True
|
||||
OnClick = Button3Click
|
||||
end
|
||||
end
|
||||
|
@ -19,16 +19,21 @@ type
|
||||
TForm4 = class(TForm, IStompClientListener)
|
||||
Button1: TButton;
|
||||
Memo1: TMemo;
|
||||
Button2: TButton;
|
||||
Button3: TButton;
|
||||
procedure Button1Click(Sender: TObject);
|
||||
procedure FormDestroy(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
procedure Button2Click(Sender: TObject);
|
||||
procedure Button3Click(Sender: TObject);
|
||||
private
|
||||
th0: IStompListener;
|
||||
th1: IStompListener;
|
||||
th2: IStompListener;
|
||||
{ Private declarations }
|
||||
FSTOMPListener: IStompListener;
|
||||
FSTOMPClient: IStompClient;
|
||||
FFormClosing: Boolean;
|
||||
FProducerThread: TThread;
|
||||
public
|
||||
procedure OnMessage(StompClient: IStompClient; StompFrame: IStompFrame;
|
||||
var StopListening: boolean);
|
||||
procedure OnStopListen(StompClient: IStompClient);
|
||||
procedure OnMessage(MessageBody: string; var TerminateListener: Boolean);
|
||||
procedure OnListenerStopped(StompClient: IStompClient);
|
||||
end;
|
||||
|
||||
var
|
||||
@ -38,92 +43,71 @@ implementation
|
||||
|
||||
uses StompClient;
|
||||
|
||||
type
|
||||
TMyStompListener = class(TInterfacedObject, IStompClientListener)
|
||||
public
|
||||
procedure OnMessage(StompClient: IStompClient; StompFrame: IStompFrame;
|
||||
var StopListening: boolean);
|
||||
procedure OnStopListen(StompClient: IStompClient);
|
||||
end;
|
||||
|
||||
{$R *.dfm}
|
||||
|
||||
|
||||
procedure TForm4.Button1Click(Sender: TObject);
|
||||
var
|
||||
stomp0: IStompClient;
|
||||
stomp1: IStompClient;
|
||||
stomp2: IStompClient;
|
||||
begin
|
||||
stomp0 := TStompClient.CreateAndConnect;
|
||||
stomp0.Subscribe('/topic/danieleteti', amAuto, StompUtils.NewHeaders.Add('include-seq', 'seq'));
|
||||
th0 := TStompClientListener.Create(stomp0, TMyStompListener.Create);
|
||||
FSTOMPListener.StopListening;
|
||||
FSTOMPListener.StartListening;
|
||||
end;
|
||||
|
||||
stomp1 := TStompClient.CreateAndConnect;
|
||||
stomp1.Subscribe('/topic/danieleteti');
|
||||
th1 := TStompClientListener.Create(stomp1, self);
|
||||
procedure TForm4.Button2Click(Sender: TObject);
|
||||
begin
|
||||
FSTOMPListener.StopListening;
|
||||
end;
|
||||
|
||||
stomp2 := TStompClient.CreateAndConnect;
|
||||
stomp2.Subscribe('/topic/salvatore');
|
||||
th2 := TStompClientListener.Create(stomp2, self);
|
||||
|
||||
TThread.CreateAnonymousThread(
|
||||
procedure TForm4.Button3Click(Sender: TObject);
|
||||
begin
|
||||
FProducerThread := TThread.CreateAnonymousThread(
|
||||
procedure
|
||||
var
|
||||
i: Integer;
|
||||
stomp: IStompClient;
|
||||
begin
|
||||
stomp := TStompClient.CreateAndConnect;
|
||||
for i := 1 to 10 do
|
||||
i := 1;
|
||||
while True do
|
||||
begin
|
||||
sleep(100);
|
||||
sleep(300);
|
||||
if FFormClosing then
|
||||
Exit;
|
||||
stomp.Send('/topic/danieleteti', 'Hello World ' + IntToStr(i));
|
||||
stomp.Send('/topic/salvatore', 'Hello World ' + IntToStr(i));
|
||||
inc(i);
|
||||
end;
|
||||
stomp.Send('/topic/danieleteti', 'SHUTDOWN');
|
||||
stomp.Send('/topic/johndoe', 'SHUTDOWN');
|
||||
stomp.Disconnect;
|
||||
end).Start;
|
||||
end;
|
||||
|
||||
procedure TForm4.OnMessage(StompClient: IStompClient; StompFrame: IStompFrame;
|
||||
var StopListening: boolean);
|
||||
begin
|
||||
if StompFrame.GetBody = 'SHUTDOWN' then
|
||||
StopListening := true;
|
||||
|
||||
TThread.Synchronize(nil,
|
||||
procedure
|
||||
begin
|
||||
Memo1.Lines.Add(StompFrame.GetBody);
|
||||
end);
|
||||
FProducerThread.FreeOnTerminate := False;
|
||||
FProducerThread.Start;
|
||||
end;
|
||||
|
||||
procedure TForm4.OnStopListen(StompClient: IStompClient);
|
||||
procedure TForm4.FormCreate(Sender: TObject);
|
||||
begin
|
||||
TThread.Synchronize(nil,
|
||||
procedure
|
||||
begin
|
||||
Memo1.Lines.Add(StompClient.GetSession + ' has been stopped');
|
||||
end);
|
||||
FFormClosing := False;
|
||||
FSTOMPClient := TStompClient.CreateAndConnect;
|
||||
FSTOMPClient.Subscribe('/topic/danieleteti',
|
||||
amAuto,
|
||||
StompUtils.Headers.Add('include-seq', 'seq'));
|
||||
FSTOMPListener := TStompClientListener.Create(FSTOMPClient, Self);
|
||||
end;
|
||||
|
||||
{ TMyStompListener }
|
||||
|
||||
procedure TMyStompListener.OnMessage(StompClient: IStompClient; StompFrame: IStompFrame;
|
||||
var StopListening: boolean);
|
||||
procedure TForm4.FormDestroy(Sender: TObject);
|
||||
begin
|
||||
if StompFrame.GetBody = 'SHUTDOWN' then
|
||||
StopListening := true;
|
||||
Writeln('------');
|
||||
Writeln(StompFrame.Output);
|
||||
Writeln('------');
|
||||
FFormClosing := True;
|
||||
FProducerThread.WaitFor;
|
||||
FProducerThread.Free;
|
||||
FSTOMPListener := nil;
|
||||
end;
|
||||
|
||||
procedure TMyStompListener.OnStopListen(StompClient: IStompClient);
|
||||
procedure TForm4.OnMessage(MessageBody: string; var TerminateListener: Boolean);
|
||||
begin
|
||||
Writeln('Listener has been stopped');
|
||||
Memo1.Lines.Add(MessageBody);
|
||||
TerminateListener := FFormClosing;
|
||||
end;
|
||||
|
||||
procedure TForm4.OnListenerStopped(StompClient: IStompClient);
|
||||
begin
|
||||
Memo1.Lines.Add('Listener Stopped');
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
@ -19,7 +19,7 @@ begin
|
||||
lClient := TStompClient.Create;
|
||||
lClient.Connect();
|
||||
WriteLn('Subscribing to queue "myqueue"');
|
||||
lClient.Subscribe('myqueue');
|
||||
lClient.Subscribe('/queue/myqueue');
|
||||
|
||||
WriteLn('Reading just the following 2 messages...');
|
||||
WriteLn(sLineBreak + sLineBreak + 'Waiting for the 1st message...' + sLineBreak +
|
||||
|
@ -172,12 +172,27 @@
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployClass Name="ProjectiOSDeviceResourceRules">
|
||||
<DeployClass Name="DependencyModule">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.dll;.bpl</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXResource">
|
||||
@ -528,27 +543,12 @@
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DependencyModule">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.dll;.bpl</Extensions>
|
||||
</Platform>
|
||||
<DeployClass Name="ProjectiOSDeviceResourceRules">
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
|
||||
|
@ -10,17 +10,21 @@ program producer;
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
StompClient;
|
||||
StompClient, StompTypes;
|
||||
|
||||
procedure Main;
|
||||
var
|
||||
lClient: TStompClient;
|
||||
lFrame: IStompFrame;
|
||||
begin
|
||||
lClient := TStompClient.Create;
|
||||
lClient.Connect();
|
||||
WriteLn('Sending messages to queue "myqueue"');
|
||||
lClient.Send('myqueue', 'Message 1');
|
||||
lClient.Send('myqueue', 'Message 2');
|
||||
lClient.Send('/queue/myqueue', 'Message 1');
|
||||
// lFrame := lClient.Receive(100);
|
||||
// if Assigned(lFrame) then
|
||||
// WriteLn(lFrame.Output);
|
||||
lClient.Send('/queue/myqueue', 'Message 2');
|
||||
WriteLn('Messages sent');
|
||||
lClient.Disconnect;
|
||||
end;
|
||||
@ -28,7 +32,7 @@ end;
|
||||
begin
|
||||
try
|
||||
Main;
|
||||
Write('Press return to quit');
|
||||
write('Press return to quit');
|
||||
ReadLn;
|
||||
except
|
||||
on E: Exception do
|
||||
|
@ -172,27 +172,12 @@
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployClass Name="DependencyModule">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.dll;.bpl</Extensions>
|
||||
</Platform>
|
||||
<DeployClass Name="ProjectiOSDeviceResourceRules">
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXResource">
|
||||
@ -543,12 +528,27 @@
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSDeviceResourceRules">
|
||||
<DeployClass Name="DependencyModule">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.dll;.bpl</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
|
||||
|
@ -9,7 +9,9 @@ program consumer;
|
||||
}
|
||||
|
||||
uses
|
||||
System.SysUtils, StompClient, StompTypes;
|
||||
System.SysUtils,
|
||||
StompClient in '..\..\StompClient.pas',
|
||||
StompTypes in '..\..\StompTypes.pas';
|
||||
|
||||
procedure Main;
|
||||
var
|
||||
@ -18,7 +20,8 @@ var
|
||||
lMessage: string;
|
||||
begin
|
||||
lClient := TStompClient.Create;
|
||||
lClient.Connect();
|
||||
lClient.SetHeartBeat(0, 0);
|
||||
lClient.Connect('127.0.0.1', 61613, '', TStompAcceptProtocol.Ver_1_1);
|
||||
WriteLn('Subscribing to queue "myjobqueue"');
|
||||
lClient.Subscribe('/topic/mytopic',
|
||||
TAckMode.amClient
|
||||
|
@ -124,6 +124,8 @@
|
||||
<DelphiCompile Include="$(MainSource)">
|
||||
<MainSource>MainSource</MainSource>
|
||||
</DelphiCompile>
|
||||
<DCCReference Include="..\..\StompClient.pas"/>
|
||||
<DCCReference Include="..\..\StompTypes.pas"/>
|
||||
<BuildConfiguration Include="Release">
|
||||
<Key>Cfg_2</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
@ -172,12 +174,27 @@
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployClass Name="ProjectiOSDeviceResourceRules">
|
||||
<DeployClass Name="DependencyModule">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.dll;.bpl</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXResource">
|
||||
@ -528,27 +545,12 @@
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DependencyModule">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.dll;.bpl</Extensions>
|
||||
</Platform>
|
||||
<DeployClass Name="ProjectiOSDeviceResourceRules">
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
|
||||
|
@ -10,7 +10,8 @@ program producer;
|
||||
|
||||
uses
|
||||
System.SysUtils,
|
||||
StompClient, StompTypes;
|
||||
StompTypes in '..\..\StompTypes.pas',
|
||||
StompClient in '..\..\StompClient.pas';
|
||||
|
||||
procedure Main;
|
||||
var
|
||||
@ -18,7 +19,8 @@ var
|
||||
lMessage: string;
|
||||
begin
|
||||
lClient := TStompClient.Create;
|
||||
lClient.Connect;
|
||||
lClient.SetHeartBeat(0, 2000);
|
||||
lClient.Connect('127.0.0.1', 61613, '', TStompAcceptProtocol.Ver_1_1);
|
||||
WriteLn('Sending messages to topic "mytopic"');
|
||||
WriteLn('NOTE: Consumers will wait a second for each "." present in the message.');
|
||||
WriteLn(' empty message will terminate the program.');
|
||||
|
@ -124,6 +124,8 @@
|
||||
<DelphiCompile Include="$(MainSource)">
|
||||
<MainSource>MainSource</MainSource>
|
||||
</DelphiCompile>
|
||||
<DCCReference Include="..\..\StompTypes.pas"/>
|
||||
<DCCReference Include="..\..\StompClient.pas"/>
|
||||
<BuildConfiguration Include="Release">
|
||||
<Key>Cfg_2</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
@ -172,27 +174,12 @@
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployClass Name="DependencyModule">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.dll;.bpl</Extensions>
|
||||
</Platform>
|
||||
<DeployClass Name="ProjectiOSDeviceResourceRules">
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXResource">
|
||||
@ -543,12 +530,27 @@
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSDeviceResourceRules">
|
||||
<DeployClass Name="DependencyModule">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.dll;.bpl</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
|
||||
|
@ -1,34 +1,61 @@
|
||||
program TestStompClient;
|
||||
{$IFDEF CONSOLE_TESTRUNNER}
|
||||
|
||||
{$IFNDEF TESTINSIGHT}
|
||||
{$APPTYPE CONSOLE}
|
||||
{$ENDIF}
|
||||
|
||||
{$ENDIF}{$STRONGLINKTYPES ON}
|
||||
uses
|
||||
Forms,
|
||||
TestFramework,
|
||||
GUITestRunner,
|
||||
TextTestRunner,
|
||||
TestStompClientU in 'TestStompClientU.pas';
|
||||
|
||||
{$R *.RES}
|
||||
System.SysUtils,
|
||||
{$IFDEF TESTINSIGHT}
|
||||
TestInsight.DUnitX,
|
||||
{$ENDIF }
|
||||
DUnitX.Loggers.Console,
|
||||
DUnitX.Loggers.Xml.NUnit,
|
||||
DUnitX.TestFramework,
|
||||
TestStompClientU in 'TestStompClientU.pas',
|
||||
StompClient in '..\StompClient.pas',
|
||||
StompTypes in '..\StompTypes.pas';
|
||||
|
||||
var
|
||||
ExCode: Integer;
|
||||
TestResult: TTestResult;
|
||||
|
||||
runner : ITestRunner;
|
||||
results : IRunResults;
|
||||
logger : ITestLogger;
|
||||
nunitLogger : ITestLogger;
|
||||
begin
|
||||
ExCode := 0;
|
||||
Application.Initialize;
|
||||
if IsConsole then
|
||||
begin
|
||||
TestResult := TextTestRunner.RunRegisteredTests;
|
||||
try
|
||||
ExCode := TestResult.ErrorCount + TestResult.FailureCount;
|
||||
finally
|
||||
TestResult.Free;
|
||||
{$IFDEF TESTINSIGHT}
|
||||
TestInsight.DUnitX.RunRegisteredTests;
|
||||
exit;
|
||||
{$ENDIF}
|
||||
try
|
||||
//Check command line options, will exit if invalid
|
||||
TDUnitX.CheckCommandLine;
|
||||
//Create the test runner
|
||||
runner := TDUnitX.CreateRunner;
|
||||
//Tell the runner to use RTTI to find Fixtures
|
||||
runner.UseRTTI := True;
|
||||
//tell the runner how we will log things
|
||||
//Log to the console window
|
||||
logger := TDUnitXConsoleLogger.Create(true);
|
||||
runner.AddLogger(logger);
|
||||
//Generate an NUnit compatible XML File
|
||||
nunitLogger := TDUnitXXMLNUnitFileLogger.Create(TDUnitX.Options.XMLOutputFile);
|
||||
runner.AddLogger(nunitLogger);
|
||||
runner.FailsOnNoAsserts := False; //When true, Assertions must be made during tests;
|
||||
|
||||
//Run tests
|
||||
results := runner.Execute;
|
||||
if not results.AllPassed then
|
||||
System.ExitCode := EXIT_ERRORS;
|
||||
|
||||
{$IFNDEF CI}
|
||||
//We don't want this happening when running under CI.
|
||||
if TDUnitX.Options.ExitBehavior = TDUnitXExitBehavior.Pause then
|
||||
begin
|
||||
System.Write('Done.. press <Enter> key to quit.');
|
||||
System.Readln;
|
||||
end;
|
||||
end
|
||||
else
|
||||
GUITestRunner.RunRegisteredTests;
|
||||
Halt(ExCode);
|
||||
{$ENDIF}
|
||||
except
|
||||
on E: Exception do
|
||||
System.Writeln(E.ClassName, ': ', E.Message);
|
||||
end;
|
||||
end.
|
||||
|
@ -1,19 +1,43 @@
|
||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<ProjectGuid>{8E4B2D47-EFD1-4ACD-9821-EF2EE2839C83}</ProjectGuid>
|
||||
<ProjectGuid>{4255F8BF-BB1B-415B-88DE-DA55867C0D40}</ProjectGuid>
|
||||
<ProjectVersion>18.1</ProjectVersion>
|
||||
<MainSource>TestStompClient.dpr</MainSource>
|
||||
<Config Condition="'$(Config)'==''">Debug</Config>
|
||||
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
|
||||
<FrameworkType>VCL</FrameworkType>
|
||||
<Base>True</Base>
|
||||
<Config Condition="'$(Config)'==''">Debug</Config>
|
||||
<Platform Condition="'$(Platform)'==''">Win32</Platform>
|
||||
<TargetedPlatforms>1025</TargetedPlatforms>
|
||||
<AppType>Application</AppType>
|
||||
<TargetedPlatforms>1</TargetedPlatforms>
|
||||
<AppType>Console</AppType>
|
||||
<FrameworkType>None</FrameworkType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Android' and '$(Base)'=='true') or '$(Base_Android)'!=''">
|
||||
<Base_Android>true</Base_Android>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='iOSDevice32' and '$(Base)'=='true') or '$(Base_iOSDevice32)'!=''">
|
||||
<Base_iOSDevice32>true</Base_iOSDevice32>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Base)'=='true') or '$(Base_iOSDevice64)'!=''">
|
||||
<Base_iOSDevice64>true</Base_iOSDevice64>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='iOSSimulator' and '$(Base)'=='true') or '$(Base_iOSSimulator)'!=''">
|
||||
<Base_iOSSimulator>true</Base_iOSSimulator>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='OSX32' and '$(Base)'=='true') or '$(Base_OSX32)'!=''">
|
||||
<Base_OSX32>true</Base_OSX32>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
|
||||
<Base_Win32>true</Base_Win32>
|
||||
<CfgParent>Base</CfgParent>
|
||||
@ -24,7 +48,7 @@
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
|
||||
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
|
||||
<Cfg_1>true</Cfg_1>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
@ -35,162 +59,467 @@
|
||||
<Cfg_1>true</Cfg_1>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
|
||||
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
|
||||
<Cfg_2>true</Cfg_2>
|
||||
<CfgParent>Base</CfgParent>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='iOSDevice64' and '$(Cfg_2)'=='true') or '$(Cfg_2_iOSDevice64)'!=''">
|
||||
<Cfg_2_iOSDevice64>true</Cfg_2_iOSDevice64>
|
||||
<CfgParent>Cfg_2</CfgParent>
|
||||
<Cfg_2>true</Cfg_2>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
|
||||
<Cfg_2_Win32>true</Cfg_2_Win32>
|
||||
<CfgParent>Cfg_2</CfgParent>
|
||||
<Cfg_2>true</Cfg_2>
|
||||
<Base>true</Base>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base)'!=''">
|
||||
<VerInfo_Keys>CompanyName=www.instantobjects.org;FileDescription=InstantObjects;FileVersion=2.1.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=InstantObjects;ProductVersion=2.1.0.0;Comments=</VerInfo_Keys>
|
||||
<VerInfo_MajorVer>2</VerInfo_MajorVer>
|
||||
<SanitizedProjectName>TestStompClient</SanitizedProjectName>
|
||||
<DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;DUnitX;$(DCC_Namespace)</DCC_Namespace>
|
||||
<VerInfo_MinorVer>1</VerInfo_MinorVer>
|
||||
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
|
||||
<VerInfo_Locale>1040</VerInfo_Locale>
|
||||
<DCC_TypedAtParameter>true</DCC_TypedAtParameter>
|
||||
<DCC_DependencyCheckOutputName>TestStompClient.exe</DCC_DependencyCheckOutputName>
|
||||
<DCC_UnitSearchPath>$(BDS)\Source\DUnit\src;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
|
||||
<DCC_Define>CONSOLE_TESTRUNNER;$(DCC_Define)</DCC_Define>
|
||||
<DCC_DcuOutput>.</DCC_DcuOutput>
|
||||
<DCC_Description>InstantObjects BDE Design-Time Support (Delphi 2010)</DCC_Description>
|
||||
<DCC_OutputNeverBuildDcps>true</DCC_OutputNeverBuildDcps>
|
||||
<DllSuffix>_D14</DllSuffix>
|
||||
<DCC_ImageBase>00400000</DCC_ImageBase>
|
||||
<DCC_Platform>x86</DCC_Platform>
|
||||
<DCC_Define>TESTINSIGHT;$(DCC_Define)</DCC_Define>
|
||||
<UsingDelphiRTL>true</UsingDelphiRTL>
|
||||
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;$(DCC_Namespace)</DCC_Namespace>
|
||||
<Icon_MainIcon>$(BDS)\bin\delphi_PROJECTICON.ico</Icon_MainIcon>
|
||||
<DCC_UnitSearchPath>$(DUnitX);$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
|
||||
<Icns_MainIcns>$(BDS)\bin\delphi_PROJECTICNS.icns</Icns_MainIcns>
|
||||
<DCC_DcuOutput>.\$(Platform)\$(Config)</DCC_DcuOutput>
|
||||
<DCC_ExeOutput>.\$(Platform)\$(Config)</DCC_ExeOutput>
|
||||
<DCC_E>false</DCC_E>
|
||||
<DCC_N>false</DCC_N>
|
||||
<DCC_S>false</DCC_S>
|
||||
<DCC_F>false</DCC_F>
|
||||
<DCC_K>false</DCC_K>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_Android)'!=''">
|
||||
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;FireDACIBDriver;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;ibmonitor;FMXTee;soaprtl;DbxCommonDriver;ibxpress;xmlrtl;soapmidas;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;$(DCC_UsePackage)</DCC_UsePackage>
|
||||
<EnabledSysJars>android-support-v4.dex.jar;cloud-messaging.dex.jar;fmx.dex.jar;google-analytics-v2.dex.jar;google-play-billing.dex.jar;google-play-licensing.dex.jar;google-play-services.dex.jar</EnabledSysJars>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_iOSDevice32)'!=''">
|
||||
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;FireDACIBDriver;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;ibmonitor;FMXTee;soaprtl;DbxCommonDriver;ibxpress;xmlrtl;soapmidas;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_iOSDevice64)'!=''">
|
||||
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;DataSnapFireDAC;tethering;rtcSDK;bindcompfmx;FmxTeeUI;FireDACIBDriver;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;rtcSDK_DBA;inet;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;ibmonitor;FMXTee;soaprtl;DbxCommonDriver;ibxpress;xmlrtl;soapmidas;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_iOSSimulator)'!=''">
|
||||
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;DBXInterBaseDriver;emsclientfiredac;DataSnapFireDAC;tethering;bindcompfmx;FmxTeeUI;FireDACIBDriver;fmx;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;soapserver;bindengine;CloudService;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;FireDACSqliteDriver;ibmonitor;FMXTee;soaprtl;DbxCommonDriver;ibxpress;xmlrtl;soapmidas;DataSnapNativeClient;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;CustomIPTransport;bindcomp;IndyIPClient;dbxcds;dsnapxml;DataSnapProviderClient;dbrtl;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_OSX32)'!=''">
|
||||
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;DataSnapServerMidas;DBXInterBaseDriver;emsclientfiredac;DataSnapFireDAC;tethering;FireDACMSSQLDriver;bindcompfmx;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;FireDACIBDriver;fmx;fmxdae;FireDACDBXDriver;dbexpress;IndyCore;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;soapserver;bindengine;DBXMySQLDriver;FireDACOracleDriver;CloudService;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;IndyIPServer;IndySystem;fmxFireDAC;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;FireDACTDataDriver;FMXTee;soaprtl;DbxCommonDriver;ibxpress;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;bindcomp;DBXInformixDriver;IndyIPClient;dbxcds;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_Win32)'!=''">
|
||||
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
|
||||
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
|
||||
<Icon_MainIcon>TestStompClient_Icon.ico</Icon_MainIcon>
|
||||
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
|
||||
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
|
||||
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;emsclientfiredac;DataSnapFireDAC;svnui;tethering;FireDACADSDriver;rtcSDK;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;svn;Intraweb;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;FireDACIBDriver;fmx;fmxdae;frx24;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;CloudService;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;rtcSDK_DBA;inet;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;soaprtl;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;frxTee24;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;frxe24;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;frxDB24;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
|
||||
<DCC_Namespace>Winapi;System.Win;Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
|
||||
<VerInfo_Locale>1033</VerInfo_Locale>
|
||||
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Base_Win64)'!=''">
|
||||
<Icon_MainIcon>TestStompClient_Icon.ico</Icon_MainIcon>
|
||||
<Manifest_File>$(BDS)\bin\default_app.manifest</Manifest_File>
|
||||
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
|
||||
<DCC_UsePackage>DBXSqliteDriver;RESTComponents;DataSnapServerMidas;DBXDb2Driver;DBXInterBaseDriver;vclactnband;vclFireDAC;emsclientfiredac;DataSnapFireDAC;tethering;FireDACADSDriver;DBXMSSQLDriver;DatasnapConnectorsFreePascal;FireDACMSSQLDriver;vcltouch;vcldb;bindcompfmx;Intraweb;DBXOracleDriver;inetdb;FmxTeeUI;emsedge;FireDACIBDriver;fmx;fmxdae;vclib;FireDACDBXDriver;dbexpress;IndyCore;vclx;dsnap;DataSnapCommon;emsclient;FireDACCommon;RESTBackendComponents;DataSnapConnectors;VCLRESTComponents;soapserver;vclie;bindengine;DBXMySQLDriver;FireDACOracleDriver;CloudService;FireDACMySQLDriver;DBXFirebirdDriver;FireDACCommonODBC;FireDACCommonDriver;DataSnapClient;inet;bindcompdbx;IndyIPCommon;vcl;DBXSybaseASEDriver;IndyIPServer;IndySystem;FireDACDb2Driver;dsnapcon;FireDACMSAccDriver;fmxFireDAC;FireDACInfxDriver;vclimg;TeeDB;FireDAC;emshosting;FireDACSqliteDriver;FireDACPgDriver;ibmonitor;FireDACASADriver;DBXOdbcDriver;FireDACTDataDriver;FMXTee;soaprtl;DbxCommonDriver;ibxpress;Tee;DataSnapServer;xmlrtl;soapmidas;DataSnapNativeClient;fmxobj;vclwinx;ibxbindings;rtl;FireDACDSDriver;DbxClientDriver;DBXSybaseASADriver;CustomIPTransport;vcldsnap;bindcomp;appanalytics;DBXInformixDriver;IndyIPClient;bindcompvcl;TeeUI;dbxcds;VclSmp;adortl;FireDACODBCDriver;DataSnapIndy10ServerTransport;dsnapxml;DataSnapProviderClient;dbrtl;inetdbxpress;FireDACMongoDBDriver;IndyProtocols;fmxase;$(DCC_UsePackage)</DCC_UsePackage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_1)'!=''">
|
||||
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
|
||||
<DCC_DebugDCUs>true</DCC_DebugDCUs>
|
||||
<DCC_Optimize>false</DCC_Optimize>
|
||||
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
|
||||
<DCC_DebugInfoInExe>true</DCC_DebugInfoInExe>
|
||||
<DCC_RemoteDebug>true</DCC_RemoteDebug>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
|
||||
<DCC_RemoteDebug>false</DCC_RemoteDebug>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_2)'!=''">
|
||||
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
|
||||
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
|
||||
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
|
||||
<DCC_DebugInformation>0</DCC_DebugInformation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
|
||||
<AppEnableHighDPI>true</AppEnableHighDPI>
|
||||
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_2)'!=''">
|
||||
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_2_iOSDevice64)'!=''">
|
||||
<BT_BuildType>Debug</BT_BuildType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
|
||||
<AppEnableHighDPI>true</AppEnableHighDPI>
|
||||
<AppEnableRuntimeThemes>true</AppEnableRuntimeThemes>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<DelphiCompile Include="$(MainSource)">
|
||||
<MainSource>MainSource</MainSource>
|
||||
</DelphiCompile>
|
||||
<DCCReference Include="TestStompClientU.pas"/>
|
||||
<BuildConfiguration Include="Debug">
|
||||
<DCCReference Include="..\StompClient.pas"/>
|
||||
<DCCReference Include="..\StompTypes.pas"/>
|
||||
<BuildConfiguration Include="Release">
|
||||
<Key>Cfg_2</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
</BuildConfiguration>
|
||||
<BuildConfiguration Include="Base">
|
||||
<Key>Base</Key>
|
||||
</BuildConfiguration>
|
||||
<BuildConfiguration Include="Release">
|
||||
<BuildConfiguration Include="Debug">
|
||||
<Key>Cfg_1</Key>
|
||||
<CfgParent>Base</CfgParent>
|
||||
</BuildConfiguration>
|
||||
</ItemGroup>
|
||||
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
|
||||
<ProjectExtensions>
|
||||
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
|
||||
<Borland.ProjectType/>
|
||||
<Borland.ProjectType>Console</Borland.ProjectType>
|
||||
<BorlandProject>
|
||||
<Delphi.Personality>
|
||||
<Parameters>
|
||||
<Parameters Name="UseLauncher">False</Parameters>
|
||||
<Parameters Name="LoadAllSymbols">True</Parameters>
|
||||
<Parameters Name="LoadUnspecifiedSymbols">False</Parameters>
|
||||
</Parameters>
|
||||
<VersionInfo>
|
||||
<VersionInfo Name="IncludeVerInfo">True</VersionInfo>
|
||||
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
|
||||
<VersionInfo Name="MajorVer">2</VersionInfo>
|
||||
<VersionInfo Name="MinorVer">1</VersionInfo>
|
||||
<VersionInfo Name="Release">0</VersionInfo>
|
||||
<VersionInfo Name="Build">0</VersionInfo>
|
||||
<VersionInfo Name="Debug">False</VersionInfo>
|
||||
<VersionInfo Name="PreRelease">False</VersionInfo>
|
||||
<VersionInfo Name="Special">False</VersionInfo>
|
||||
<VersionInfo Name="Private">False</VersionInfo>
|
||||
<VersionInfo Name="DLL">False</VersionInfo>
|
||||
<VersionInfo Name="Locale">1040</VersionInfo>
|
||||
<VersionInfo Name="CodePage">1252</VersionInfo>
|
||||
</VersionInfo>
|
||||
<VersionInfoKeys>
|
||||
<VersionInfoKeys Name="CompanyName">www.instantobjects.org</VersionInfoKeys>
|
||||
<VersionInfoKeys Name="FileDescription">InstantObjects</VersionInfoKeys>
|
||||
<VersionInfoKeys Name="FileVersion">2.1.0.0</VersionInfoKeys>
|
||||
<VersionInfoKeys Name="InternalName"/>
|
||||
<VersionInfoKeys Name="LegalCopyright"/>
|
||||
<VersionInfoKeys Name="LegalTrademarks"/>
|
||||
<VersionInfoKeys Name="OriginalFilename"/>
|
||||
<VersionInfoKeys Name="ProductName">InstantObjects</VersionInfoKeys>
|
||||
<VersionInfoKeys Name="ProductVersion">2.1.0.0</VersionInfoKeys>
|
||||
<VersionInfoKeys Name="Comments"/>
|
||||
</VersionInfoKeys>
|
||||
<Excluded_Packages>
|
||||
<Excluded_Packages Name="C:\Users\Public\Documents\RAD Studio\7.0\Bpl\dclHengenOPFCore.bpl">Hengen OPF Core</Excluded_Packages>
|
||||
<Excluded_Packages Name="C:\Users\Public\Documents\RAD Studio\7.0\Bpl\HengenOPFCore.bpl">Hengen Computing OPF</Excluded_Packages>
|
||||
<Excluded_Packages Name="C:\Users\Public\Documents\RAD Studio\7.0\Bpl\dclHengenADOLayer.bpl">Hengen ADO Persistence Layer</Excluded_Packages>
|
||||
<Excluded_Packages Name="C:\Users\Public\Documents\RAD Studio\7.0\Bpl\dclHengenIBXLayer.bpl">Hengen IBX Persistence Layer</Excluded_Packages>
|
||||
<Excluded_Packages Name="C:\Users\Public\Documents\RAD Studio\7.0\Bpl\dclHengenOPFGUI.bpl">Hengen OPF GUI Controls</Excluded_Packages>
|
||||
<Excluded_Packages Name="C:\Users\Public\Documents\RAD Studio\7.0\Bpl\dclObjectListMgrMediators.bpl">Hengen OPF ObjectListMgr Demo Mediators</Excluded_Packages>
|
||||
<Excluded_Packages Name="C:\Users\Public\Documents\RAD Studio\7.0\Bpl\Spring.Core.bpl">Delphi Spring Framework Core Library</Excluded_Packages>
|
||||
<Excluded_Packages Name="C:\Users\Public\Documents\RAD Studio\7.0\Bpl\Spring.Base.bpl">Delphi Spring Framework Base Class Library</Excluded_Packages>
|
||||
<Excluded_Packages Name="$(BDSBIN)\bcboffice2k140.bpl">Embarcadero C++Builder Office 2000 Servers Package</Excluded_Packages>
|
||||
<Excluded_Packages Name="$(BDSBIN)\bcbofficexp140.bpl">Embarcadero C++Builder Office XP Servers Package</Excluded_Packages>
|
||||
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k140.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
|
||||
<Excluded_Packages Name="$(BDSBIN)\dclofficexp140.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
|
||||
</Excluded_Packages>
|
||||
<Source>
|
||||
<Source Name="MainSource">TestStompClient.dpr</Source>
|
||||
</Source>
|
||||
</Delphi.Personality>
|
||||
<UnitTesting>
|
||||
<TestFramework>DUnit / Delphi Win32</TestFramework>
|
||||
<TestRunner>Console</TestRunner>
|
||||
<TestProjectName/>
|
||||
<SourceProjectName/>
|
||||
</UnitTesting>
|
||||
<Deployment Version="3">
|
||||
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgunwind.1.0.dylib" Class="DependencyModule">
|
||||
<Platform Name="OSX32">
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libcgunwind.1.0.dylib" Class="DependencyModule">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="$(BDS)\Redist\iossimulator\libPCRE.dylib" Class="DependencyModule">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="$(BDS)\Redist\osx32\libcgsqlite3.dylib" Class="DependencyModule">
|
||||
<Platform Name="OSX32">
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployFile LocalName="Win32\Debug\TestStompClient.exe" Configuration="Debug" Class="ProjectOutput">
|
||||
<Platform Name="Win32">
|
||||
<RemoteName>TestStompClient.exe</RemoteName>
|
||||
<Overwrite>true</Overwrite>
|
||||
</Platform>
|
||||
</DeployFile>
|
||||
<DeployClass Name="ProjectiOSDeviceResourceRules"/>
|
||||
<DeployClass Name="ProjectOSXResource">
|
||||
<Platform Name="OSX32">
|
||||
<RemoteDir>Contents\Resources</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidClassesDexFile">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>classes</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AdditionalDebugSymbols">
|
||||
<Platform Name="Win32">
|
||||
<RemoteDir>Contents\MacOS</RemoteDir>
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch768">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon144">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xxhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidLibnativeMipsFile">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\mips</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Required="true" Name="ProjectOutput">
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Linux64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DependencyFramework">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.framework</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch640">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch1024">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSDeviceDebug">
|
||||
<Platform Name="iOSDevice64">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<RemoteDir>..\$(PROJECTNAME).app.dSYM\Contents\Resources\DWARF</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch320">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSInfoPList"/>
|
||||
<DeployClass Name="AndroidLibnativeArmeabiFile">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DebugSymbols">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPad_Launch1536">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage470">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-normal</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon96">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xhdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage640">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-large</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="iPhone_Launch640x1136">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSEntitlements"/>
|
||||
<DeployClass Name="Android_LauncherIcon72">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-hdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidGDBServer">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectOSXInfoPList"/>
|
||||
<DeployClass Name="ProjectOSXEntitlements"/>
|
||||
<DeployClass Name="iPad_Launch2048">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidSplashStyles">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\values</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage426">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-small</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidSplashImageDef">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectiOSResource">
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="ProjectAndroidManifest">
|
||||
<Platform Name="Android">
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_DefaultAppIcon">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="File">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="Android">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>0</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="AndroidServiceOutput">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>library\lib\armeabi-v7a</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Required="true" Name="DependencyPackage">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.bpl</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice64">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSDevice32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="iOSSimulator">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon48">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-mdpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_SplashImage960">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-xlarge</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="Android_LauncherIcon36">
|
||||
<Platform Name="Android">
|
||||
<RemoteDir>res\drawable-ldpi</RemoteDir>
|
||||
<Operation>1</Operation>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<DeployClass Name="DependencyModule">
|
||||
<Platform Name="Win32">
|
||||
<Operation>0</Operation>
|
||||
<Extensions>.dll;.bpl</Extensions>
|
||||
</Platform>
|
||||
<Platform Name="OSX32">
|
||||
<Operation>1</Operation>
|
||||
<Extensions>.dylib</Extensions>
|
||||
</Platform>
|
||||
</DeployClass>
|
||||
<ProjectRoot Platform="iOSDevice64" Name="$(PROJECTNAME).app"/>
|
||||
<ProjectRoot Platform="Win64" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="iOSDevice32" Name="$(PROJECTNAME).app"/>
|
||||
<ProjectRoot Platform="Linux64" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="Win32" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="OSX32" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="Android" Name="$(PROJECTNAME)"/>
|
||||
<ProjectRoot Platform="iOSSimulator" Name="$(PROJECTNAME).app"/>
|
||||
</Deployment>
|
||||
<Platforms>
|
||||
<Platform value="iOSDevice64">True</Platform>
|
||||
<Platform value="Android">False</Platform>
|
||||
<Platform value="iOSDevice32">False</Platform>
|
||||
<Platform value="iOSDevice64">False</Platform>
|
||||
<Platform value="iOSSimulator">False</Platform>
|
||||
<Platform value="OSX32">False</Platform>
|
||||
<Platform value="Win32">True</Platform>
|
||||
<Platform value="Win64">False</Platform>
|
||||
</Platforms>
|
||||
</BorlandProject>
|
||||
<ProjectFileVersion>12</ProjectFileVersion>
|
||||
</ProjectExtensions>
|
||||
<Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
|
||||
<Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
|
||||
<Import Project="$(MSBuildProjectName).deployproj" Condition="Exists('$(MSBuildProjectName).deployproj')"/>
|
||||
</Project>
|
||||
|
Binary file not shown.
@ -3,31 +3,74 @@ unit TestStompClientU;
|
||||
interface
|
||||
|
||||
uses
|
||||
TestFramework;
|
||||
DUnitX.TestFramework, StompClient, StompTypes, System.Diagnostics, System.SysUtils;
|
||||
|
||||
type
|
||||
TTestStompClient = class(TTestCase)
|
||||
published
|
||||
procedure TestAssertTrue;
|
||||
procedure TestAssertFalse;
|
||||
|
||||
[TestFixture]
|
||||
TTestSTOMP = class(TObject)
|
||||
private
|
||||
FSTOMP: IStompClient;
|
||||
public
|
||||
[Setup]
|
||||
procedure Setup;
|
||||
[TearDown]
|
||||
procedure TearDown;
|
||||
// Sample Methods
|
||||
// Simple single Test
|
||||
[Test]
|
||||
procedure TestPubSub10;
|
||||
// Test with TestCase Attribute to supply parameters.
|
||||
// [Test]
|
||||
// [TestCase('TestA', '1,2')]
|
||||
// [TestCase('TestB', '3,4')]
|
||||
// procedure Test2(const AValue1: Integer; const AValue2: Integer);
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TTestStompClient }
|
||||
|
||||
procedure TTestStompClient.TestAssertFalse;
|
||||
procedure TTestSTOMP.Setup;
|
||||
begin
|
||||
CheckTrue(false);
|
||||
// FSTOMP := TStompClient.CreateAndConnect('127.0.0.1', 61613, '',
|
||||
// TStompAcceptProtocol.Ver_1_0);
|
||||
end;
|
||||
|
||||
procedure TTestStompClient.TestAssertTrue;
|
||||
procedure TTestSTOMP.TearDown;
|
||||
begin
|
||||
CheckTrue(true);
|
||||
// FSTOMP := nil;
|
||||
end;
|
||||
|
||||
procedure TTestSTOMP.TestPubSub10;
|
||||
var
|
||||
lFrame: IStompFrame;
|
||||
lSW: TStopWatch;
|
||||
lSTOMP: IStompClient;
|
||||
I: Integer;
|
||||
begin
|
||||
lSTOMP := TStompClient.Create;
|
||||
lSTOMP.SetHeartBeat(1000, 0);
|
||||
lSTOMP.Connect('127.0.0.1', 61613, '', TStompAcceptProtocol.Ver_1_1);
|
||||
lSTOMP.Subscribe('/topic/mytopic');
|
||||
Sleep(10000);
|
||||
lSTOMP.Send('/topic/mytopic', 'Hello World1');
|
||||
lSTOMP.Send('/topic/mytopic', 'Hello World2');
|
||||
lSTOMP.Send('/topic/mytopic', 'Hello World3');
|
||||
lSTOMP.Send('/topic/mytopic', 'Hello World4');
|
||||
lSTOMP.Send('/topic/mytopic', 'Hello World5');
|
||||
|
||||
lSW := TStopWatch.Create;
|
||||
for I := 1 to 5 do
|
||||
begin
|
||||
lFrame := lSTOMP.Receive(5000);
|
||||
Assert.IsTrue(lSW.ElapsedMilliseconds <= 50);
|
||||
Assert.IsNotNull(lFrame, 'Message not received by the sender');
|
||||
Assert.AreEqual('Hello World' + I.ToString, lFrame.Body);
|
||||
end;
|
||||
lFrame := lSTOMP.Receive(50);
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
||||
RegisterTest(TTestStompClient.Suite);
|
||||
TDUnitX.RegisterTestFixture(TTestSTOMP);
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user