📄 utcmppcom.pas
字号:
Result := ICP_ERR_SUBMITERR;
end;
wrError:
begin
Result := ICP_ERR_SUBMITERR;
end;
end;
//删除对象
csWaitMsg.Enter;
WaitList.Remove(MsgWait);
csWaitMsg.Leave;
if Result = 0 then
begin
//返回消息处理
tmpMsgID := MsgWait.MsgID;
tmpMsgID := ntohll(tmpMsgID);
tmpMsgIDStr :=
IntToHex(tmpMsgID and $000000000000FFFF, 4) + //序列号
IntToHex((tmpMsgID and $0000003FFFFF0000) shr 16, 6) + //短信网关代码
IntToHex((tmpMsgID and $F000000000000000) shr 60, 2) + //月份的二进制表示
IntToHex((tmpMsgID and $0F80000000000000) shr 55, 2) + //日的二进制表示
IntToHex((tmpMsgID and $007C000000000000) shr 50, 2) + //小时的二进制表示
IntToHex((tmpMsgID and $0003F00000000000) shr 44, 2) + //分的二进制表示
IntToHex((tmpMsgID and $00000FC000000000) shr 38, 2); //秒的二进制表示
StrPLCopy(Pchar(@pSubmitInfo^.sMsgID), tmpMsgIDStr, 21);
Result := MsgWait.Status;
end
else
begin
//如果没有返回则有可能是没有发出去,此时要删除队列
csSendMsg.Enter;
if SendList.Remove(pMsg) <> -1 then
Dispose(pMsg);
csSendMsg.Leave;
end;
//s释放对象
MsgWait.Free;
except
end;
end;
function TCMPPService.CMPPMsg_SeTCMPPMsgHeadEx(pMsg: PCMPPMsgHead; MsgCode, MsgLen,
SwquenceID: Integer): integer;
begin
Result := MsgLen + sizeof(TCMPPMsgHead);
pMsg.PacketLength := htonl(Result);
pMsg.Command_Id := htonl(MsgCode);
pMsg.SwquenceID := htonl(SwquenceID);
end;
procedure TCMPPService.ClearList;
var
i : integer;
MsgWait : TCMPPMsgWait;
pMsg : PCMPPDeliverResp;
begin
//清理发送队列
csWaitMsg.Enter;
SysLog.LogInfo('Clear WaitList Count= ' + IntToStr(WaitList.Count));
if WaitList.Count > 0 then
for i := WaitList.Count - 1 to 0 do
begin
MsgWait := WaitList[i];
MsgWait.WaitEvent.SetEvent;
end;
csWaitMsg.Leave;
// 清理接收队列
csRecMsg.Enter;
SysLog.LogInfo('Clear RecQueue Count= ' + IntToStr(RecQueue.Count));
if RecQueue.Count > 0 then
for i := RecQueue.Count - 1 to 0 do
begin
//取消息
pMsg := PCMPPDeliverResp(RecQueue.Pop);
//释放内存
Dispose(pMsg);
end;
csRecMsg.Leave;
SysLog.LogInfo('Clear End');
end;
procedure TCMPPService.SetWaitMsg(ASwquenceID: integer; Status: Integer; MsgID: Int64);
var
TmpWait : TCMPPMsgWait;
i : integer;
begin
csWaitMsg.Enter;
for i := 0 to WaitList.Count - 1 do
begin
TmpWait := WaitList[i];
if TmpWait.FSwquenceID = ASwquenceID then
begin
TmpWait.Status := Status;
TmpWait.MsgID := MsgID;
TmpWait.WaitEvent.SetEvent;
end;
end;
csWaitMsg.Leave;
end;
procedure TCMPPService.Execute;
var
Msg : tagMSG;
begin
inherited;
InitSys;
while not (Terminated) and GetMessage(Msg, 0, 0, 0) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
UnInitSys;
end;
procedure TCMPPService.InitSys;
begin
InitParam;
SetServiceStatus(SS_IDLE);
//事件
ServiceEvent := TEvent.Create(nil, False, False, '');
//队列
csSendMsg := TCriticalSection.Create;
SendEvent := TEvent.Create(nil, False, False, '');
csWaitMsg := TCriticalSection.Create;
RecEvent := TEvent.Create(nil, False, False, '');
csRecMsg := TCriticalSection.Create;
SendList := TList.Create;
WaitList := TList.Create;
RecQueue := TQueue.Create;
//定时器
ReConTimer := TTimer.Create(nil);
ReConTimer.Enabled := False;
ReConTimer.OnTimer := ReConTimerDo;
ActiveTimer := TTimer.Create(nil);
ActiveTimer.Interval := 20000;
ActiveTimer.Enabled := True;
ActiveTimer.OnTimer := ActiveTimerDo;
//Socket
CMPPClient := TClientSocket.Create(nil);
csSocket := TCriticalSection.Create;
MsgSend := TCMPPMsgSendThread.Create(Self);
with CMPPClient do
begin
Active := False;
Address := ServiceIP;
Port := ServicePort;
ClientType := ctNonBlocking;
//分配事件处理代码
OnConnect := CMPP_ConnectSuc;
OnDisconnect := CMPP_DisConnect;
OnError := CMPP_Error;
OnWrite := CMPP_CanWrite;
OnRead := CMPP_Read;
end;
ClientSeqID := 0;
bServiceActive := False;
bComCanWrite := False;
bComReboot := False;
end;
procedure TCMPPService.UnInitSys;
begin
Stop;
MsgSend.Resume;
MsgSend.Terminate;
CMPPClient.Free;
csSocket.Free;
ReConTimer.Free;
ActiveTimer.Free;
SendList.Free;
WaitList.Free;
RecQueue.Free;
csSendMsg.Free;
csWaitMsg.Free;
csRecMsg.Free;
SendEvent.Free;
RecEvent.Free;
ServiceEvent.Free;
end;
procedure TCMPPService.ActiveTimerDo(Sender: TObject);
begin
if bServiceActive and bComCanWrite then
CMPPMsg_SendActive;
end;
function TCMPPService.CMPPMsg_SendActive: integer;
var
Len : integer;
PMsg : PChar;
begin
{ DONE : 发送Exit消息 }
//组合消息
Len := CMPPMsg_SeTCMPPMsgHead(@CMPPMsg_Active, CMD_ACTIVE, 0);
//发送消息
PMsg := @CMPPMsg_Active;
Result := CMPPMsg_Send(PMsg^, Len);
end;
function TCMPPService.AddSubmitMsgEx(pSubmitInfo: PCMPPSubmit): integer;
var
pMsg : PCMPPMsg_Submit;
pMsgSub : PCMPPMsgBody_Submit_Sub;
Len : Integer;
SwquenceID : Integer;
MsgWait : TCMPPMsgWait;
UserNum : integer;
UserTel : TStrings;
tmpMsgID : integer;
tmpMsgIDStr : string;
begin
//如果服务没有启动,则返回
try
if not bServiceActive then
begin
Result := ICP_ERR_NOLOGIN;
exit;
end;
//如果socket在 重新连接,则返回
if bComReboot then
begin
Result := ICP_ERR_CONTRETRY;
exit;
end;
//如果发送窗口满了,则返回
if (WaitList.Count + SendList.Count) >= RequestWindow * 1.5 then
begin
Result := ICP_ERR_SUBMITOUTOFWINDOW;
exit;
end;
//组合消息
new(pMsg);
ZeroMemory(pMsg, sizeof(TCMPPMsg_Submit));
with pMsg.Body, pSubmitInfo^ do
begin
Msg_Id := 0;
Pk_total := byPKTotal;
Pk_number := byPKNumber;
Registered_Delivery := byneedReport;
Msg_level := byMsglevel;
StrLCopy(@Service_Id, @sServiceID, 10);
Fee_UserType := byFeeUserType;
StrLCopy(@Fee_terminal_Id, @sFeeAddr, 20);
Fee_terminal_type := bychargTermidType;
TP_pId := byPID;
TP_udhi := byUDHI;
Msg_Fmt := byMsg_Fmt;
StrLCopy(@Msg_src, @sSPID, 6);
StrLCopy(@FeeType, @sFeeType, 2);
StrLCopy(@FeeCode, @sFeeCode, 6);
StrLCopy(@ValId_Time, @sSchedule, 17);
StrLCopy(@At_Time, @sExpire, 17);
StrLCopy(@Src_Id, @sOrgAddr, 20);
UserTel := TStringList.Create;
try
UserTel.Delimiter := ';';
UserTel.DelimitedText := StrPas(@sDestAddrs);
DestUsr_tl := UserTel.Count;
if DestUsr_tl > 100 then
DestUsr_tl := 100;
for UserNum := 0 to DestUsr_tl - 1 do
begin
StrLCopy(Pchar(Integer(@Dest_terminal_Id) + UserNum * 32), PChar(UserTel[UserNum]), 32);
end
finally
UserTel.Free;
end;
pMsgSub := PCMPPMsgBody_Submit_Sub((Pchar(@Dest_terminal_Id) + DestUsr_tl * 32));
pMsgSub^.Dest_terminal_type := byDestTerminalType;
pMsgSub^.Msg_Length := byUDLen;
if pMsgSub^.Msg_Length > 160 then
pMsgSub^.Msg_Length := 160;
StrLCopy(@pMsgSub^.Msg_Content, @sUserData, pMsgSub^.Msg_Length);
StrLCopy(Pchar(Integer(@pMsgSub^.Msg_Content) + pMsgSub^.Msg_Length), @sLinkID, 20);
Len := sizeof(TCMPPMsgBody_SubmitHead) + DestUsr_tl * 32 + 22 +
pMsgSub^.Msg_Length;
end;
CMPPMsg_SeTCMPPMsgHead(@(pMsg^.Head), CMD_SUBMIT, Len);
SwquenceID := ntohl(pMsg.Head.SwquenceID);
//添加到队列
csSendMsg.Enter;
SendList.Add(pMsg);
//激活等待发送线程
if MsgSend.Suspended then
begin
MsgSend.Suspended := False;
end;
csSendMsg.Leave;
//在等待队列中等待返回 sMsgID, nErrorCode,
{ DONE : 在等待队列中等待返回 sMsgID, nErrorCode, }
//创建等待对象,
MsgWait := TCMPPMsgWait.Create(SwquenceID);
csWaitMsg.Enter;
WaitList.Add(MsgWait);
csWaitMsg.Leave;
//等待返回消息
case MsgWait.WaitEvent.WaitFor(3000) of //
wrSignaled:
begin
//结果赋值
Result := 0;
end;
wrTimeout:
begin
Result := ICP_ERR_SUBMITTIMEOUT;
end;
wrAbandoned:
begin
Result := ICP_ERR_SUBMITERR;
end;
wrError:
begin
Result := ICP_ERR_SUBMITERR;
end;
end;
//删除对象
csWaitMsg.Enter;
WaitList.Remove(MsgWait);
csWaitMsg.Leave;
if Result = 0 then
begin
//返回消息处理
tmpMsgID := MsgWait.MsgID;
tmpMsgID := ntohll(tmpMsgID);
tmpMsgIDStr :=
IntToHex(tmpMsgID and $000000000000FFFF, 4) + //序列号
IntToHex((tmpMsgID and $0000003FFFFF0000) shr 16, 6) + //短信网关代码
IntToHex((tmpMsgID and $F000000000000000) shr 60, 2) + //月份的二进制表示
IntToHex((tmpMsgID and $0F80000000000000) shr 55, 2) + //日的二进制表示
IntToHex((tmpMsgID and $007C000000000000) shr 50, 2) + //小时的二进制表示
IntToHex((tmpMsgID and $0003F00000000000) shr 44, 2) + //分的二进制表示
IntToHex((tmpMsgID and $00000FC000000000) shr 38, 2); //秒的二进制表示
StrPLCopy(Pchar(@pSubmitInfo^.sMsgID), tmpMsgIDStr, 21);
Result := MsgWait.Status;
end
else
begin
//如果没有返回则有可能是没有发出去,此时要删除队列
csSendMsg.Enter;
if SendList.Remove(pMsg) <> -1 then
Dispose(pMsg);
csSendMsg.Leave;
end;
//s释放对象
MsgWait.Free;
except
end;
end;
{ TCMPPMsgSendThread }
constructor TCMPPMsgSendThread.Create(AService: TCMPPService);
begin
inherited Create(True);
FService := AService;
FreeOnTerminate := True;
SysLog.LogInfo('Thread Create');
end;
destructor TCMPPMsgSendThread.Destroy;
begin
inherited;
end;
procedure TCMPPMsgSendThread.Execute;
var
PMsg : PCMPPMsg_Submit;
bHadMsg : Boolean;
i : Integer;
begin
inherited;
//未设置停止标志前一直运行
//FService.bComCanWrite FService.bComReboot FService.bServiceActive
// FService.SendList.Count FService.SendList[0]
while not (Terminated) do
begin
//从队列中获取数据然后发送
with FService do
begin
if bServiceActive and bComCanWrite and not bComReboot and (WaitList.Count
< RequestWindow) then
begin
//验证是否有消息需要发送 ,如果没有等待
if (SendList.Count = 0) and not Self.Suspended then
begin
Self.Suspended := True;
end;
{ if SendList.Count = 0 then
begin
case SendEvent.WaitFor(2000) of //
wrSignaled:
begin
bHadMsg := True;
end;
wrTimeout:
begin
bHadMsg := False;
end;
wrAbandoned:
begin
bHadMsg := False;
end;
wrError:
begin
bHadMsg := False;
end;
end;
end
else
begin
bHadMsg := True;
end; }
csSendMsg.Enter;
if //bHadMsg and
(SendList.Count > 0) then
begin
//取消息
for i := SendList.Count - 1 downto 0 do
begin
PMsg := PCMPPMsg_Submit(SendList[i]);
SendList.Delete(i);
//发送
if CMPPMsg_Send(PMsg^, ntohl(pmsg^.Head.PacketLength)) = -1 then
begin
SysLog.LogInfo('发送数据出错!');
end
else
begin
//SysLog.LogInfo('发送消息成功!Seq=');
//SysLog.LogInfo(PMsg, ntohl(pmsg^.Head.PacketLength));
end;
//发送完释放内存
Dispose(PMsg);
end;
end;
csSendMsg.Leave;
end
else
begin
// 如果暂时不能发送,则休息
Sleep(300);
end;
end;
end;
end;
{ TCMPPMsgWait }
constructor TCMPPMsgWait.Create;
begin
WaitEvent := TEvent.Create(nil, False, False, '');
FSwquenceID := ASwquenceID;
end;
destructor TCMPPMsgWait.Destroy;
begin
WaitEvent.Free;
inherited;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -