利用静态数组在MQ中发送接收字符串

利用静态数组发送接收字符串,字符串长度超出数组大小时分割为多条消息

 unit UMQ_PutGetPas;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, CMQPas, CMQBPas, CMQCFPas, CMQPSPas, CMQXPas,
  CMQZPas, ExtCtrls,XMLDoc, jpeg;

type
  TFrmMain = class(TForm)
    edtQM: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    edtQN: TEdit;
    btnOpenQM: TButton;
    Sb1: TStatusBar;
    memSendStr: TMemo;
    btnSendQueue: TButton;
    memAcceptStr: TMemo;
    btnAcceptQueue: TButton;
    btnCloseQM: TButton;
    Timer1: TTimer;
    chkEnableAccept: TCheckBox;
    btnCancelAccept: TButton;
    procedure btnOpenQMClick(Sender: TObject);
    procedure btnCloseQMClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure btnCancelAcceptClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure btnSendQueueClick(Sender: TObject);
    procedure btnAcceptQueueClick(Sender: TObject);
  private
    { Private declarations }
    FCancelAccept:Boolean;
    //分解字符串,取出以回车结尾的最大长度的字符串
    function MakeStr(MsgStr: String; iLen,OldRow: Integer;var CurRow,TotalRow:Integer): String;
    //发送消息
    function SendStrMsg(MsgStr:String):Boolean;
    //接收消息
    function GetStrMsg(MsgList:TStrings):Boolean;
  public
    { Public declarations }
  end;

var
  FrmMain: TFrmMain;
  Hconn    : MQHCONN;   // Connection handle
  CompCode : MQLONG;    // Completion code - used by all routines
  OpenCode : MQLONG;    // Completion code - used by MQOPEN function
  Reason   : MQLONG;    // Reason code - used by all function
  CReason  : MQLONG;    // Connect Reason code qualifying CompCode
  O_options: MQLONG;    // Open connection flags
  C_options: MQLONG;    // Close connection flags
  HObj     : MQHOBJ;

  od       : TMQOD;      // Object descriptor
  gmo      : TMQGMO;     // Get message options
  md       : TMQMD;      // message descripton structure
  pmo      : TMQPMO;     // Put message options
  buffer: array[0..1000*8] of char;  // message buffer in which program receive messages
  buflen: MQLONG;                 // buffer length - 1 - zero terminated for strings
  messlen: MQLONG;                // message length received - number of bytes I want to send or I received

  QueueName          : String;
  QueueManagerName   : String;
  MessageStr         : String;
implementation

{$R *.dfm}

procedure TFrmMain.btnOpenQMClick(Sender: TObject);
begin
  if Trim(edtQN.Text)='' then
  begin
     sb1.Panels[0].Text:='队列名称出错!';
     Exit;
  end;

  // ****************************************
  // Step 1 - 连接到连接管理器
  // ****************************************
  QueueManagerName:=Trim(edtQM.Text);
  MQCONN(Pchar(QueueManagerName), // Connection manager name
         HConn,                   // Connection Handle
         CompCode,                // Completition Code
         CReason);                // Reason

  if (CompCode <> MQCC_OK) then
  begin
    sb1.Panels[0].Text:=Format('MQCONN调用失败,代码:[%d] 原因:[%d]', [CompCode, Reason]);
    Exit;
  end
  else
    sb1.Panels[0].Text:='队列管理器打开';

  // *****************************************
  // Step 2 - 打开队列
  // *****************************************
  // reset object descriptor structure to defaults
  QueueName:=Trim(edtQN.Text);
  SetMQOD_DEFAULT(od);

  // copy queue name string to object structure
  StrPLCopy(od.ObjectName, QueueName, SizeOf(od.ObjectName));

  // Set connection options
  O_options := MQOO_INPUT_AS_Q_DEF       // open queue for input  - read, get
             + MQOO_OUTPUT               // open queue for output - write, put
             + MQOO_FAIL_IF_QUIESCING;   // but not if Message Queue Manager is in stopping state
  if chkEnableAccept.checked then
     O_options := MQOO_OUTPUT               // open queue for output - write, put
                + MQOO_FAIL_IF_QUIESCING;   // but not if Message Queue Manager is in stopping state

  // Finally open queue
  MQOPEN(Hconn,            // connection handle
          od,              // object descriptor for queue
          O_options,       // open options
          Hobj,            // object handle
          OpenCode,        // completion code
          Reason);         // reason code

  // Check the results of openning action
  if (Reason <> MQRC_NONE) then
  begin
    sb1.Panels[0].Text:=Format('MQOPEN执行结束,代码:[%d] 原因:[%d]', [OpenCode, Reason]);
    Exit;
  end;

  if (OpenCode = MQCC_FAILED) then
  begin
    sb1.Panels[0].Text:=Format('无法打开输入或输出队列,代码:[%d] 原因:[%d]', [OpenCode, Reason]);
    Exit;
  end;

  sb1.Panels[0].Text:='队列已打开';
end;

procedure TFrmMain.btnCloseQMClick(Sender: TObject);
begin
  // ***************************************
  // Step 5 - 关闭连接到队列的连接
  // ***************************************
  if (OpenCode <> MQCC_FAILED) then
  begin
    C_options := 0;                  // no close options
    MQCLOSE(Hconn,                   // connection handle
            Hobj,                    // object handle
            C_options,               // close options
            CompCode,                // completion code
            Reason);                 // reason code

    if (Reason <> MQRC_NONE) then
      Sb1.Panels[0].Text:=Format('MQCLOSE执行结束,代码:[%d] 原因:[%d]', [CompCode, Reason])
    else
      Sb1.Panels[0].Text:='队列已关闭';
  end;

  // ***********************************************
  // Step 6 - 关闭连接到队列管理器的连接
  // ***********************************************
  MQDISC(Hconn,                  // connection handle
         CompCode,               // completion code
         Reason);                // reason code

  if (Reason <> MQRC_NONE) then
    Sb1.Panels[0].Text:=Format('MQDISC执行结束,代码:[%d] 原因:[%d]', [CompCode, Reason])
  else
    Sb1.Panels[0].Text:='队列管理器关闭';
end;

procedure TFrmMain.Timer1Timer(Sender: TObject);
begin
 btnAcceptQueue.Click;
end;
//取消接收
procedure TFrmMain.btnCancelAcceptClick(Sender: TObject);
begin
 FCancelAccept:=True;
end;

procedure TFrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 btnCloseQM.Click;
end;

//分解字符串,取出以回车结尾的最大长度的字符串
function TFrmMain.MakeStr(MsgStr: String; iLen, OldRow: Integer;
  var CurRow,TotalRow: Integer): String;
var
 StrList:TStringList;
 NewStr,TmpStr,RetStr:String;
 I:Integer;
begin
 NewStr:=MsgStr;
 try
   StrList:=TStringList.Create;
   while True do
   begin
    TmpStr:='';
    I:=Pos(#13,NewStr);
    if I>0 then
    begin
     TmpStr:=Copy(NewStr,1,I);
     StrList.Add(TmpStr);
     NewStr:=Copy(NewStr,I+1,Length(NewStr)-Length(TmpStr));
    end
    else
    if NewStr<>'' then
    begin
     StrList.Add(NewStr);
     Break;
    end;//if
    if NewStr='' then
     Break;
    Application.ProcessMessages;
   end;//while
   TotalRow:=StrList.Count;
   TmpStr:='';
   RetStr:='';
   I:=0;
   while True do
   begin
    Inc(I);
    if I<OldRow+1 then
    begin
     Continue;
    end;
    if I>TotalRow then Break;
    TmpStr:=StrList.Strings[I-1];
    if Length(TmpStr)+Length(RetStr)>iLen then//-10
     Break;
    if RetStr='' then
     RetStr:=TmpStr
    else
     RetStr:=RetStr+#13+TmpStr;
    Application.ProcessMessages;
   end;//while
   CurRow:=I-OldRow-1;
 finally
   StrList.Free;
 end;
 Result:=RetStr;
end;

function TFrmMain.GetStrMsg(MsgList: TStrings): Boolean;
var
 LoopNum:Integer;
begin
  // *******************************************
  // Step 4 - 循环从队列中读取消息
  // *******************************************
  Result:=False;
  FCancelAccept:=False;

  Screen.Cursor:=crHourGlass;
  // reset Get Message Option structure to defaults
  SetMQMD_DEFAULT(md);
  SetMQGMO_DEFAULT(gmo);

  //gmo.Version = MQGMO_VERSION_2;  // Avoid need to reset Message
  //gmo.MatchOptions = MQMO_NONE;   // ID and Correlation ID after
                                     // every MQGET
  gmo.Options :=MQGMO_WAIT         // wait for new messages  //
 //              +MQGMO_SYNCPOINT
               + MQGMO_CONVERT;     // convert if necessary
  //gmo.WaitInterval := 15000;        // 1 seconds limit for waiting

  // assume that everything is OK with - see loop condition
  CompCode := MQCC_OK;

  // how much bytes my receive buffer can handle
  // note - in this application my send and receive buffers are the same
  FillChar(buffer, SizeOf(Buffer), 0);
  buflen := SizeOf(buffer) - 1;

  // enter loop in which programm receives messages from queue
  LoopNum:=0;
  while (CompCode <> MQCC_FAILED) do
  begin
    if FCancelAccept then
    begin
      Sb1.Panels[0].Text:='用户取消接收消息';
      Screen.Cursor:=crDefault;
      exit;
    end;//if
    // before message is received you always must
    // reset this fields in Messsage Descriptor structure
    move(MQMI_NONE, md.MsgId, SizeOf(md.MsgId));
    move(MQCI_NONE, md.CorrelId, SizeOf(md.CorrelId));
    md.Encoding       := MQENC_NATIVE;
    md.CodedCharSetId := MQCCSI_Q_MGR;

    MQGET(Hconn,              // connection handle
          Hobj,               // object handle
          md,                 // message descriptor
          gmo,                // get message options
          buflen,             // buffer length
          @buffer,            // message buffer
          messlen,            // message length
          CompCode,           // completion code
          Reason);            // reason code

    if (CompCode <> MQCC_FAILED) then
    begin
       Inc(LoopNum);
       MsgList.Add(Buffer);
       Sb1.Panels[1].Text:='读取次数:'+IntToStr(LoopNum);
    end
    else
    begin
      if (Reason = MQRC_NO_MSG_AVAILABLE) then begin
          Sb1.Panels[0].Text:=Format('没有消息,代码:[%d] 原因:[%d]', [CompCode, Reason]);
      end
      else
      if (Reason <> MQRC_NONE) then //获取消息失败
      begin
        Screen.Cursor:=crDefault;
        Exit;
      end;//if
    end;//if
    //重要:多次读取必须重新初始化Buffer
    FillChar(buffer, SizeOf(Buffer), 0);
    application.ProcessMessages;
  end;//while
  Screen.Cursor:=crDefault;
end;

function TFrmMain.SendStrMsg(MsgStr: String): Boolean;
var
 TotalRow,OldRow,CurRow:Integer;
 I:Integer;
 TmpStr:String;
begin
  // *****************************************
  // Step 3 - 把测试消息放入队列中
  // *****************************************
  // reset message descriptor structure to defaults
  Result:=False;
  SetMQMD_DEFAULT(md);

  // Copy my custom message string to my local buffer
  FillChar(buffer, SizeOf(Buffer), 0);
  buflen := SizeOf(buffer) - 1;
  SetMQPMO_DEFAULT(pmo);
  md.Format := MQFMT_STRING;
  //
  OldRow:=0;
  TotalRow:=1;
  while OldRow<TotalRow do
  begin
   TmpStr:=MakeStr(MsgStr,BufLen,OldRow,CurRow,TotalRow);
   OldRow:=OldRow+CurRow;
   FillChar(buffer, SizeOf(Buffer), 0);
   StrPLCopy(buffer, TmpStr,SizeOf(buffer));
   MQPUT(Hconn,             // connection handle
          Hobj,              // object handle
          md,                // message descriptor
          pmo,               // default options (datagram)
          Length(TmpStr),    // message length
          @buffer,           // pointer to message buffer
          CompCode,          // completion code
          Reason);           // reason code
    if (Reason <> MQRC_NONE) then
    begin
      Result:=False;
      Exit;
    end;
    Application.ProcessMessages;
  end;//while
  Result:=True;
end;

procedure TFrmMain.btnSendQueueClick(Sender: TObject);
begin
 Sb1.Panels[0].Text:='正在发送消息到队列...';
 if SendStrMsg(memSendStr.Text) then
   Sb1.Panels[0].Text:='消息已放入队列中'
 else
   Sb1.Panels[0].Text:=Format('MQPUT执行失败,代码:[%d] 原因:[%d]', [CompCode, Reason]);
end;

procedure TFrmMain.btnAcceptQueueClick(Sender: TObject);
begin

  Sb1.Panels[0].Text:='每隔1S读取一次队列...';
  if GetStrMsg(MemAcceptStr.Lines) then
   Sb1.Panels[0].Text:='消息读取成功。'
  else
   Sb1.Panels[0].Text:=Format('获取消息失败,代码:[%d] 原因:[%d]', [CompCode, Reason]);
end;

end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值