<strong><span style="font-size:18px;color:#ff0000;">下面的代码中包含了一个消息接收器,当消息接收器收到消息后,将socket,收到的消息,状态,封装成对象,保存到tstringlist中,stringlist.strings[0]里面保存了对象的ID(也就是命令的序号,从1..X);然后放一个定时器,定时器1S中去查看命令列表;把第一条命令的stringlist.strings[0]设置为‘0’,如果定时器检查到第一条的这个标志是0,则退出,不处理。证明系统正在处理其中的一条命令。把这个命令发送给子的socketserver; 在clientread里读取数据,然后处理,处理完后,返回信息回去,证明这个命令处理完了,把处理的状态返回给消息发送器。然后调用命令对象里的socket发送给命令发送者,去掉第一条命令。 然后定时器检测到命令存在时,发送命令,设置状态。知道处理完所有的命令。</span></strong>
<pre name="code" class="delphi">procedure write_log(str: string);
var
F: TextFile;
mfile: string;
begin
try
//判断保存日志文件的目录是否存在
if not DirectoryExists(ExtractFilePath(ParamStr(0)) + 'log') then
MkDir(ExtractFilePath(ParamStr(0)) + 'log');
//按日期及时间设定保存日志的文件名
mfile := ExtractFilePath(ParamStr(0)) + 'log\' + formatdatetime('yyyy-mm-dd', now) + '.txt';
AssignFile(F,mfile);
if not FileExists(mfile) then
Rewrite(F);//如果文件不存在,则创建一个新的文件,并写入
Append(F); //追加写入
Writeln(F,str);//写入并换行
CloseFile(F);
except
end;
end;
procedure TfmDKGZT.DJsocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
sReceive, sDJBH: string;
slReceive: TStringList;
begin
// 如果需要做批发,uni_basedatabill里的Execute;重新打开单据上的监听端口;
// 因为每张单据需要一个监听端口,再打开别的单据之前,请关掉别的端口;
// 这个时候需要在每个命令中保存要打开的单据号。
slReceive := TStringList.Create;
sReceive := socket.ReceiveText;
slReceive.CommaText := sReceive;
sDJBH := slReceive[0];
if FMainTbl.Locate('DJBH',SDJBH) then
begin
if isWJSNOprint and (GetNameFromCode('DKGZT','DJBH','YS',SDJBH)<>'1') then
begin
socket.SendText('1');
Exit;
end;
DiyPrint;
write_log('【' + FormatDateTime('yyyy-mm-dd hh:nn:ss ',Now) + '单据打印成功】'+'单据编号:'+SDJBH);
write_log('【' + FormatDateTime('yyyy-mm-dd hh:nn:ss ',Now) + '】'+'------------------------------------');
socket.SendText('0');
end
else
begin
socket.SendText('2');
end;
end;
// 创建窗体的时候,打开socket;
configIni := Tinifile.Create(ExtractFilePath(Paramstr(0))+'SysBusiness.ini');
DK := configIni.ReadInteger('PORTS','DKGTX_N',3005);
configini.Free;
DJsocket.Port := DK;
try
DJsocket.Open;
write_log('【' + FormatDateTime('yyyy-mm-dd hh:nn:ss ',Now) + '监听服务已打开】'+'端口号:'+inttostr(DJsocket.port));
except
on E:Exception do
begin
if pos('10048',E.Message)>0 then
Uni_Function.ShowApplicationMsg('端口:'+inttostr(DK)+'被占用,将无法通过IPAD调用打印服务!',IERRORMSG);
end;
end;
TDKGZTXX = class
Fsocket: TCustomWinSocket;
FTxt:String;
Fstate: integer;
public
constructor create();
end;
procedure Tfrm_MainForm.mainSerSocketClientRead(Sender: TObject;
Socket: TCustomWinSocket);
var
acceptList: TStringList;
acceptStr: String;
modid, strimodid: string;
imodid,DK,POS_i: integer;
configIni: Tinifile;
dkgztxx: TDKGZTXX;
begin
//这里不一定是一次接收,一个命令,有可能一次接收了多个命令。
acceptStr:= socket.ReceiveText;
// write_log('【' + FormatDateTime('yyyy-mm-dd hh:nn:ss ',Now) + '收到加密消息】'+socket.RemoteAddress+':'+inttostr(socket.RemotePort)+':'+inttostr(socket.SocketHandle)+':'+acceptStr);
acceptstr := Uni_Dlls.Encryption(acceptstr, false);
write_log('【' + FormatDateTime('yyyy-mm-dd hh:nn:ss ',Now) + '收到打印请求】'+socket.RemoteAddress+':'+inttostr(socket.RemotePort)+':'+acceptStr);
POS_i :=posEX('81006006',acceptstr,9);
if pos_i >0 then
begin
while pos_i>0 do
begin
inc(taskcount);
dkgztxx := Tdkgztxx.Create;
dkgztxx.Fsocket := socket;
dkgztxx.FTxt := leftstr(acceptstr,pos_i-1);
acceptstr := midstr(acceptstr,pos_i,10000);
POS_i :=posEX('81006006',acceptstr,9);
tasklist.AddObject(inttostr(taskcount),dkgztxx);
write_log('【' + FormatDateTime('yyyy-mm-dd hh:nn:ss ',Now) + '加到任务列表】'+socket.RemoteAddress+':'+inttostr(socket.RemotePort)+'*'+inttostr(taskcount)+'*'+dkgztxx.FTxt);
end;
end;
inc(taskcount);
dkgztxx := Tdkgztxx.Create;
dkgztxx.Fsocket := socket;
dkgztxx.FTxt := acceptstr;
tasklist.AddObject(inttostr(taskcount),dkgztxx);
write_log('【' + FormatDateTime('yyyy-mm-dd hh:nn:ss ',Now) + '加到任务列表】'+socket.RemoteAddress+':'+inttostr(socket.RemotePort)+'*'+inttostr(taskcount)+'*'+dkgztxx.FTxt);
time_socket.Enabled := true;
end;
constructor TDKGZTXX.create;
begin
Fstate :=0;
end;
procedure Tfrm_MainForm.time_socketTimer(Sender: TObject);
var
acceptList: TStringList;
acceptStr: String;
modid, strimodid: string;
imodid,DK,i: integer;
configIni: Tinifile;
dkgztxx: TDKGZTXX;
sendmessage: string;
begin
// 如果任务队列中没数据,则退出。
if tasklist.Count = 0 then
begin
time_socket.Enabled := false;
exit;
end;
// 如果第一条数据的索引字符串是'0’,表示第一条记录还没打印,继续等待打印
// 结束,不进行处理。
if tasklist.Strings[0] = '0' then exit;
acceptList := TStringList.Create;
dkgztxx := Tdkgztxx(tasklist.Objects[0]);
acceptList.CommaText := dkgztxx.FTxt ;
modid := acceptlist[0];
acceptlist.Delete(0);
sendmessage := acceptlist.CommaText;
acceptlist.Free;
// 分离出第一个命令,打开窗体;
if not isWindowExists(modid, True) then
begin
if length(modid)<3 then exit;
striModid:=copy(modid,2,2);
iModId:=StrToInt(striModid);
Uni_RunForms.ActivateMdiChildForm(iModId, modid,
OUser.Power.GetFuncAlias(modid), '', _bsBrowse);
write_log('【' + FormatDateTime('yyyy-mm-dd hh:nn:ss ',Now) + '单据打开】'+dkgztxx.Fsocket.Remoteaddress+':'+inttostr(dkgztxx.Fsocket.RemotePort)+':'+modid);
// 创建窗体的时候,打开socket;
configIni := Tinifile.Create(ExtractFilePath(Paramstr(0))+'SysBusiness.ini');
DK := configIni.ReadInteger('PORTS','DKGTX_N',3005);
configini.Free;
mainCSocket.Port := DK;
mainCSocket.Open;
end;
//刚开启端口的时候,active不一定打开
if maincsocket.Active then
begin
maincsocket.Socket.SendText(sendmessage);
write_log('【' + FormatDateTime('yyyy-mm-dd hh:nn:ss ',Now) + '内部信息发送】'+dkgztxx.Fsocket.Remoteaddress+':'+inttostr(dkgztxx.Fsocket.RemotePort)+':'+sendmessage);
tasklist.Strings[0] :='0';
end;
end;
procedure Tfrm_MainForm.FormDestroy(Sender: TObject);
begin
tasklist.Free;
end;
procedure Tfrm_MainForm.mainCSocketRead(Sender: TObject;
Socket: TCustomWinSocket);
var
dkgztxx: TDKGZTXX;
jo,jt:ISuperObject;
printstr,strN: string;
begin
dkgztxx := Tdkgztxx(tasklist.Objects[0]);
try
// status 是否成功标志 0 失败 >0 成功 message 成功消息/ 活着失败原因 data: 就返回那个单据编号吧
jt := SO();
jt.S['status'] := '0';
jt.s['data'] := midstr(dkgztxx.FTxt,10,1000);
strN := socket.ReceiveText;
if strN = '0' then
begin
jt.S['message'] :='打印成功!';
end else if strN = '1' then
begin
jt.S['status'] := '1';
jt.S['message'] :='未结算不可打印!';
end else
begin
jt.S['message'] :='未找到单据';
jt.S['status'] := '1';
end;
printstr := jt.s['data']+jt.S['message'];
dkgztxx.FSocket.SendText(jt.AsString);
write_log('【' + FormatDateTime('yyyy-mm-dd hh:nn:ss ',Now) + '对外发送消息】'+jt.AsString);
except
on E: Exception do
showmessage(E.Message);
end;
dkgztxx.Free;
tasklist.Delete(0);
// write_log('【' + FormatDateTime('yyyy-mm-dd hh:nn:ss ',Now) + '内部信息接收】'+strN);
end;
procedure Tfrm_MainForm.mainSerSocketClientError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
errorcode :=0;
end;