You are not logged in.
Pages: 1
Yes, of course, you're absolutely right.
I know now, how I can do. I will use the code of SockReceiveString and will add a timeout.
Thanks for the answer.
My needs are, binary exchanges (no CR/LF) and possibility to send data at any time (not only in response of something).
Currently I use the Indy components.
Now, I try to use the TCrtSocket to replace the Indy component (For better performances and better mORMot integration).
The test code is :
var
TCP: TCrtSocket;
s: RawByteString;
str: RawByteString;
begin
TCP := Open('localhost', '9999');
if TCP<>nil then
try
while true do
begin
str := 'hello';
if not TCP.TrySndLow(@str[1], 5) then
begin
writeln('Snd error');
break;
end;
Sleep(500);
end;
if not TCP.SockConnected then
writeln('not connected');
finally
TCP.Free;
end;
end.
When I stop the server, TCP.SockConnected continues to return the value true.
How can I test the connection status?
Another issue is the following :
The code below will never stops if I stop the server. The execution loops forever in SockReceiveString.
var
TCP: TCrtSocket;
StrReceived: RawByteString;
begin
TCP := Open('localhost', '9999');
if TCP<>nil then
try
while true do
begin
StrReceived := TCP.SockReceiveString();
writeln(StrReceived);
Sleep(500);
end;
finally
TCP.Free;
end;
end.
En fait, j'ai prévu d'utiliser un extrait du code de SockeReceivedString en ajoutant un test avec SockConnected. Mais SockConnected semble ne pas fonctionner.
For information, the OTL library is limited to 64 threads.
In my usage :
- Each thread contain only one mORMont Client.
- Each application launches 50 threads
- I launch the application several times with different parameters to reach 1000 clients.
But...
Finally I have followed one of your suggestions. I manage several clients in one thread. And I launch several threads (I removed the OTL library because it was the first time I used it, so I'm not an expert. I will certainly give it another try, later).
At first glance, this solution works really better (no errors).
Thanks a lot.
The server is on the same host.
Here is the log of the server.
C:\PcmClients\PcmClientsServer.exe 0.0.0.0 (2014-06-30 09:04:35)
Host=PC-THPF-OLD User=rsi CPU=8*9-6-7685 OS=13.1=6.1.7601 Wow64=1 Freq=2727587
Environment variables=ALLUSERSPROFILE=C:\ProgramData APPDATA=C:\Users\rsi\AppData\Roaming CommonProgramFiles=C:\Program Files (x86)\Common Files CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files CommonProgramW6432=C:\Program Files\Common Files COMPUTERNAME=PC-THPF-OLD ComSpec=C:\Windows\system32\cmd.exe FP_NO_HOST_CHECK=NO HOMEDRIVE=C: HOMEPATH=\Users\rsi LOCALAPPDATA=C:\Users\rsi\AppData\Local LOGONSERVER=\\PC-THPF-OLD NUMBER_OF_PROCESSORS=8 OS=Windows_NT Path=C:\Program Files (x86)\Embarcadero\RADStudio\12.0\bin;C:\Users\Public\Documents\RAD Studio\12.0\Bpl;C:\Program Files (x86)\Embarcadero\RADStudio\12.0\bin64;C:\Users\Public\Documents\RAD Studio\12.0\Bpl\Win64;C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\bin;C:\Users\rsi\Documents\RAD Studio\12.0\Bpl;C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\bin64;C:\Users\rsi\Documents\RAD Studio\12.0\Bpl\Win64;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Users\Public\Documents\RAD Studio\12.0\Bpl PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC PROCESSOR_ARCHITECTURE=x86 PROCESSOR_ARCHITEW6432=AMD64 PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 30 Stepping 5, GenuineIntel PROCESSOR_LEVEL=6 PROCESSOR_REVISION=1e05 ProgramData=C:\ProgramData ProgramFiles=C:\Program Files (x86) ProgramFiles(x86)=C:\Program Files (x86) ProgramW6432=C:\Program Files PROMPT=$P$G PSModulePath=C:\Windows\system32\WindowsPowerShell\v1.0\Modules\ PUBLIC=C:\Users\Public SESSIONNAME=Console SystemDrive=C: SystemRoot=C:\Windows TEMP=C:\Users\rsi\AppData\Local\Temp TMP=C:\Users\rsi\AppData\Local\Temp USERDOMAIN=PC-ThPf-old USERNAME=rsi USERPROFILE=C:\Users\rsi windir=C:\Windows windows_tracing_flags=3 windows_tracing_logfile=C:\BVTBin\Tests\installpackage\csilogfile.log __COMPAT_LAYER=RunAsAdmin
TSQLLog 1.18 2014-07-01T15:25:10
20140701 15251046 EXC EHttpApiServer ("HttpSendHttpResponse failed: Une opération a été tentée sur une connexion réseau qui n’existe pas (1229)") at 00223997 SynCrtSock.EHttpApiServer.RaiseOnError (4735) stack trace 000BE6DC System.Classes.ThreadProc (14601) 00009BF6 System.ThreadWrapper (23707)
20140701 15251208 EXC EHttpApiServer ("HttpSendHttpResponse failed: Une opération a été tentée sur une connexion réseau qui n’existe pas (1229)") at 00223997 SynCrtSock.EHttpApiServer.RaiseOnError (4735) stack trace 000BE6DC System.Classes.ThreadProc (14601) 00009BF6 System.ThreadWrapper (23707)
20140701 15251211 EXC EHttpApiServer ("HttpSendHttpResponse failed: Une opération a été tentée sur une connexion réseau qui n’existe pas (1229)") at 00223997 SynCrtSock.EHttpApiServer.RaiseOnError (4735) stack trace 000BE6DC System.Classes.ThreadProc (14601) 00009BF6 System.ThreadWrapper (23707)
20140701 15251328 EXC EHttpApiServer ("HttpSendHttpResponse failed: Une opération a été tentée sur une connexion réseau qui n’existe pas (1229)") at 00223997 SynCrtSock.EHttpApiServer.RaiseOnError (4735) stack trace 000BE6DC System.Classes.ThreadProc (14601) 00009BF6 System.ThreadWrapper (23707)
20140701 15251345 EXC EHttpApiServer ("HttpSendHttpResponse failed: Une opération a été tentée sur une connexion réseau qui n’existe pas (1229)") at 00223997 SynCrtSock.EHttpApiServer.RaiseOnError (4735) stack trace 000BE6DC System.Classes.ThreadProc (14601) 00009BF6 System.ThreadWrapper (23707)
20140701 15251355 EXC EHttpApiServer ("HttpSendHttpResponse failed: Une opération a été tentée sur une connexion réseau qui n’existe pas (1229)") at 00223997
I also added these parameters in the registry:
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Tcpip\Parameters]
"MaxUserPorts"=dword:0000ea60
"EnableConnectionRateLimiting"=dword:00000000
But this changes nothing.
I also installed the test onto another host (clients and server):
- Windows server 2008, R2
- Intel Xeon CPU E31230, 3,2GHz, 32 GB ram, 64 bits
The result is the same.
On this host, i'm sure the limitation of simultaneous TCP connections are greater than 20000, because I've made succesful tests with 20000 simultaneus TCP connexions (onto a server based on this IOCP framework http://www.serverframework.com/ )
The sample 21 works well.
Test started with 500 threads, 100 client(s) per thread and 10000 rows to be inserted...
Assertion(s) failed: 0 / 40496
Number of clients connected at once: 50000
Time to process: 7.13s
Operation per second: 2804
The mORMot server and clients are on the same host.
PROCESSOR_LEVEL=6
---
To facilitate the analysis, I removed from my code all the parts that doesn't concern the mORMot.
So the main unit shrinks from 1471 lines to 149 lines.
I redid all the tests.
The main unit:
unit PcmClient;
interface
uses
System.SysUtils, System.Variants, System.Classes, System.Generics.Collections, System.Types, TypInfo, IniFiles, DateUtils, Winapi.WinSock,
IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdGlobal, IdHash, IdHashMessageDigest, IdException, IdExceptionCore,
SynCommons, mORMot, mORMotSQLite3, SynSQLite3Static, mORMotHttpClient, SynMustache,
PcmClientData;
type
TPcmClient = class
private
ClId: integer;
LogClId: RawUTF8;
PcmClientModel: TSQLModel;
OrmClient: TSQLRestClientURI;
PcmClientConfig: TSQLPcmClientConfig;
PcmClientAction: TSQLPcmClientAction;
NextActionIndex: integer;
procedure GetNextAction;
procedure ProcessActionChangeProperty;
procedure ProcessActionEvent;
procedure ProcessActionFile;
procedure ProcessActionHeartbeat;
public
constructor Create(aId: integer); overload;
destructor Destroy; override;
procedure Execute;
end;
implementation
constructor TPcmClient.Create(aId: integer);
var
SynLog: ISynLog;
begin
inherited Create;
SynLog := TSQLLog.Enter(Self);
ClId := aId;
LogClId := RawUTF8(IntToStr(ClId) + '>');
PcmClientModel := CreatePcmClientModel;
OrmClient := TSQLHttpClient.Create(HOST_NAME, PORT_NAME, PcmClientModel);
PcmClientConfig := TSQLPcmClientConfig.Create(OrmClient, ClId);
PcmClientAction := TSQLPcmClientAction.Create();
NextActionIndex := 0;
GetNextAction;
if PcmClientConfig.ID <> ClId then
SynLog.Log(sllCustom1, 'Client id doens''t exists:' + IntToStr(ClId))
else
SynLog.Log(sllCustom1, LogClId + PcmClientConfig.SerialNumber);
end;
destructor TPcmClient.Destroy();
begin
PcmClientConfig.Free;
OrmClient.Free;
PcmClientModel.Free;
inherited;
end;
procedure TPcmClient.GetNextAction;
begin
Inc(NextActionIndex);
PcmClientAction.Offset := 0;
OrmClient.Retrieve('ClId = ? AND Idx = ?', [], [ClId, NextActionIndex], PcmClientAction);
PcmClientAction.Init;
end;
procedure TPcmClient.Execute;
var
SynLog: ISynLog;
begin
SynLog := TSQLLog.Enter(Self);
repeat
// Here is normally the IdSocket processing
// The code below is executed on E: EIdReadTimeout
if PcmClientAction.CanExecuteNow then
begin
case PcmClientAction.Act of
acNone: ;
acConnect: ;
acDisconnect: ;
acHeartbeat: ProcessActionHeartbeat;
acChangeProperty: ProcessActionChangeProperty;
acEvent: ProcessActionEvent;
acFile: ProcessActionFile;
end;
GetNextAction;
end;
Sleep(100);
until false;
end;
procedure TPcmClient.ProcessActionHeartbeat;
var
Activity: integer;
begin
Activity := StrToIntDef(PcmClientAction.Data, 0);
TSynLog.Add.Log(sllCustom1, LogClId + PcmClientAction.Desc);
end;
procedure TPcmClient.ProcessActionChangeProperty;
var
PropName: RawUTF8;
PropValue: RawUTF8;
SynLog: ISynLog;
begin
SynLog := TSQLLog.Enter(Self);
begin
SynCommons.Split(PcmClientAction.Data, '|', PropName, PropValue);
if PcmClientConfig.PropertyExists(PropName) then
begin
PcmClientConfig.SetPropertyValue(PropName, PropValue);
SynLog.Log(sllCustom1, LogClId + PcmClientAction.Desc);
end;
end;
end;
procedure TPcmClient.ProcessActionEvent;
var
EventName: RawUTF8;
Attributes: RawUTF8;
AttributesList: TRawUTF8List;
SynLog: ISynLog;
begin
SynLog := TSQLLog.Enter(Self);
SynCommons.Split(PcmClientAction.Data, '|', EventName, Attributes);
SynLog.Log(sllCustom1, LogClId + PcmClientAction.Desc);
end;
procedure TPcmClient.ProcessActionFile();
var
FileName: RawUTF8;
MetaData: RawUTF8;
MetaDataList: TRawUTF8List;
FileData: TSQLRawBlob;
SynLog: ISynLog;
begin
SynLog := TSQLLog.Enter(Self);
SynCommons.Split(PcmClientAction.Data, '|', FileName, MetaData);
OrmClient.RetrieveBlob(TSQLPcmClientAction, PcmClientAction.ID, 'FileData', FileData);
SynLog.Log(sllCustom1, LogClId + PcmClientAction.Desc);
end;
end.
Here the project code. I use the OTL library.
program PcmClients;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils, IdExceptionCore,
SynCommons, mORMot,
OtlParallel, OtlTask,
PcmClient in 'PcmClient.pas',
PcmClientData in 'PcmClientData.pas';
var
i: integer;
StartIndex: integer;
EndIndex: integer;
begin
with TSQLLog.Family do
begin
// ExceptionIgnore.Add(EIdReadTimeout);
PerThreadLog := ptOneFilePerThread;
DestinationPath := ExtractFilePath(ParamStr(0));
Level := LOG_STACKTRACE + [sllCustom1];
EchoToConsole := Level;
end;
StartIndex := StrToIntDef(ParamStr(1), 1);
EndIndex := StrToIntDef(ParamStr(2), 1);
for i := StartIndex to EndIndex do
begin
Parallel.Async(
procedure
var
PcmClient: TPcmClient;
begin
try
PcmClient := TPcmClient.Create(i);
PcmClient.Execute;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end);
// Il faut une pause entre chaque démarrage car sinon on a une erreur sur l'accès au fichier .map si on l'utilise
Sleep(1000);
end;
end.
The application are lauched several times like this.
The parameters are the clients ID.
start PcmClients.exe 1 50
pause
start PcmClients.exe 51 100
pause
start PcmClients.exe 101 150
pause
start PcmClients.exe 151 200
pause
There is no problem up to 700 clients. With 800 clients the errors appear.
The database for the clients is created by a separated tool.
The actions are created randomly for each client.
For this test, there are 5 "static" files for the action "File" : (21, 25, 48, 71, 782 Kb).
Below a log from a client (without .map file)
C:\PcmClients\1\PcmClients.exe 0.0.0.0 (2014-07-01 08:28:12)
Host=PC-THPF-OLD User=rsi CPU=8*9-6-7685 OS=13.1=6.1.7601 Wow64=1 Freq=2727587
Environment variables=ALLUSERSPROFILE=C:\ProgramData APPDATA=C:\Users\rsi\AppData\Roaming CommonProgramFiles=C:\Program Files (x86)\Common Files CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files CommonProgramW6432=C:\Program Files\Common Files COMPUTERNAME=PC-THPF-OLD ComSpec=C:\Windows\system32\cmd.exe FP_NO_HOST_CHECK=NO HOMEDRIVE=C: HOMEPATH=\Users\rsi LOCALAPPDATA=C:\Users\rsi\AppData\Local LOGONSERVER=\\PC-THPF-OLD NUMBER_OF_PROCESSORS=8 OS=Windows_NT Path=C:\Program Files (x86)\Embarcadero\RADStudio\12.0\bin;C:\Users\Public\Documents\RAD Studio\12.0\Bpl;C:\Program Files (x86)\Embarcadero\RADStudio\12.0\bin64;C:\Users\Public\Documents\RAD Studio\12.0\Bpl\Win64;C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\bin;C:\Users\rsi\Documents\RAD Studio\12.0\Bpl;C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\bin64;C:\Users\rsi\Documents\RAD Studio\12.0\Bpl\Win64;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Users\Public\Documents\RAD Studio\12.0\Bpl PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC PROCESSOR_ARCHITECTURE=x86 PROCESSOR_ARCHITEW6432=AMD64 PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 30 Stepping 5, GenuineIntel PROCESSOR_LEVEL=6 PROCESSOR_REVISION=1e05 ProgramData=C:\ProgramData ProgramFiles=C:\Program Files (x86) ProgramFiles(x86)=C:\Program Files (x86) ProgramW6432=C:\Program Files PROMPT=$P$G PSModulePath=C:\Windows\system32\WindowsPowerShell\v1.0\Modules\ PUBLIC=C:\Users\Public SESSIONNAME=Console SystemDrive=C: SystemRoot=C:\Windows TEMP=C:\Users\rsi\AppData\Local\Temp TMP=C:\Users\rsi\AppData\Local\Temp USERDOMAIN=PC-ThPf-old USERNAME=rsi USERPROFILE=C:\Users\rsi windir=C:\Windows windows_tracing_flags=3 windows_tracing_logfile=C:\BVTBin\Tests\installpackage\csilogfile.log
TSQLLog 1.18 2014-07-01T09:04:00
20140701 09040029 cust1 58>E030000013080058
20140701 09042822 cust1 58>[58] (1) PropertyChanged
20140701 09043523 cust1 58>[58] (2) Event
20140701 09045614 cust1 58>[58] (3) PropertyChanged
20140701 09051136 cust1 58>[58] (4) PropertyChanged
20140701 09054648 cust1 58>[58] (5) PropertyChanged
20140701 09062323 cust1 58>[58] (6) File
20140701 09071113 cust1 58>[58] (7) File
20140701 09074113 cust1 58>[58] (8) Event
20140701 09083228 EXC EWinHTTP ("winhttp.dll error 12002 ()") at 0068E483 stack trace 00406A52 0040A1D0 0040A433 00405A61 00406A8F 0040ADE0 005657A2 00561BEF 00561F8E 00561F9B 00692100 006921A0 00699BBB 005FD864 005E47BA 005E3D66 004086F6 0040DE30 0040DDC8 005E3B77
20140701 09085844 cust1 58>[58] (9) File
Below a log from a client (with .map file)
C:\PcmClients\5\PcmClients.exe 0.0.0.0 (2014-07-01 09:15:23)
Host=PC-THPF-OLD User=rsi CPU=8*9-6-7685 OS=13.1=6.1.7601 Wow64=1 Freq=2727587
Environment variables=ALLUSERSPROFILE=C:\ProgramData APPDATA=C:\Users\rsi\AppData\Roaming CommonProgramFiles=C:\Program Files (x86)\Common Files CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files CommonProgramW6432=C:\Program Files\Common Files COMPUTERNAME=PC-THPF-OLD ComSpec=C:\Windows\system32\cmd.exe FP_NO_HOST_CHECK=NO HOMEDRIVE=C: HOMEPATH=\Users\rsi LOCALAPPDATA=C:\Users\rsi\AppData\Local LOGONSERVER=\\PC-THPF-OLD NUMBER_OF_PROCESSORS=8 OS=Windows_NT Path=C:\Program Files (x86)\Embarcadero\RADStudio\12.0\bin;C:\Users\Public\Documents\RAD Studio\12.0\Bpl;C:\Program Files (x86)\Embarcadero\RADStudio\12.0\bin64;C:\Users\Public\Documents\RAD Studio\12.0\Bpl\Win64;C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\bin;C:\Users\rsi\Documents\RAD Studio\12.0\Bpl;C:\Program Files (x86)\Embarcadero\RAD Studio\12.0\bin64;C:\Users\rsi\Documents\RAD Studio\12.0\Bpl\Win64;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Users\Public\Documents\RAD Studio\12.0\Bpl PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC PROCESSOR_ARCHITECTURE=x86 PROCESSOR_ARCHITEW6432=AMD64 PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 30 Stepping 5, GenuineIntel PROCESSOR_LEVEL=6 PROCESSOR_REVISION=1e05 ProgramData=C:\ProgramData ProgramFiles=C:\Program Files (x86) ProgramFiles(x86)=C:\Program Files (x86) ProgramW6432=C:\Program Files PROMPT=$P$G PSModulePath=C:\Windows\system32\WindowsPowerShell\v1.0\Modules\ PUBLIC=C:\Users\Public SESSIONNAME=Console SystemDrive=C: SystemRoot=C:\Windows TEMP=C:\Users\rsi\AppData\Local\Temp TMP=C:\Users\rsi\AppData\Local\Temp USERDOMAIN=PC-ThPf-old USERNAME=rsi USERPROFILE=C:\Users\rsi windir=C:\Windows windows_tracing_flags=3 windows_tracing_logfile=C:\BVTBin\Tests\installpackage\csilogfile.log
TSQLLog 1.18 2014-07-01T09:18:36
20140701 09183603 cust1 820>E030000013080820
20140701 09192811 cust1 820>[820] (1) File
20140701 09200453 cust1 820>[820] (2) PropertyChanged
20140701 09200458 EXC EWinHTTP ("winhttp.dll error 12002 ()") at 002A9F79 SynCrtSock.RaiseLastModuleError (1787) stack trace 00005A52 System.@GetMem (4356) 000091D0 System.@NewAnsiString (24002) 00009433 System.@LStrFromPCharLen (24750) 00009BCE System.@LStrCatN (27273) 001917B7 mORMot.TSQLRestClientURI.ExecuteList (24212) 00189DE6 mORMot.TSQLModelRecordProperties.SQLFromSelectWhere (22004) 0018D381 mORMot.TSQLRest.Retrieve (22910) 0018D769 mORMot.TSQLRest.Retrieve (23006) 00005A6E System.@FreeMem (4404) 002AE02B PcmClient.TPcmClient.GetNextAction (70) 002AE0DD PcmClient.TPcmClient.Execute (94) 002B5B6A PcmClients.PcmClients$6083$ActRec.$0$Body (39) 00217857 OtlParallel.Parallel.Async$5257$ActRec.$0$Body (1635) 001FCA0A OtlTaskControl.TOmniTaskExecutor.Asy_Execute (1632) 001FBD8B OtlTaskControl.TOmniTask.InternalExecute (1356) 0000A9DD System.@FinalizeRecord (31190) 000076AB System.TObject.GetInterface (15953) 0000CE30 System.TInterfacedObject.QueryInterface (36456)
20140701 09200558 EXC EWinHTTP ("winhttp.dll error 12002 ()") at 002A9F79 SynCrtSock.RaiseLastModuleError (1787) stack trace 00005A52 System.@GetMem (4356) 000091D0 System.@NewAnsiString (24002) 00009433 System.@LStrFromPCharLen (24750) 00009BCE System.@LStrCatN (27273) 001917B7 mORMot.TSQLRestClientURI.ExecuteList (24212) 00189DE6 mORMot.TSQLModelRecordProperties.SQLFromSelectWhere (22004) 0018D381 mORMot.TSQLRest.Retrieve (22910) 0018D769 mORMot.TSQLRest.Retrieve (23006) 002AE02B PcmClient.TPcmClient.GetNextAction (70) 002AE0DD PcmClient.TPcmClient.Execute (94) 002B5B6A PcmClients.PcmClients$6083$ActRec.$0$Body (39) 00217857 OtlParallel.Parallel.Async$5257$ActRec.$0$Body (1635) 001FCA0A OtlTaskControl.TOmniTaskExecutor.Asy_Execute (1632) 001FBD8B OtlTaskControl.TOmniTask.InternalExecute (1356) 0000A9DD System.@FinalizeRecord (31190) 000076AB System.TObject.GetInterface (15953) 0000CE30 System.TInterfacedObject.QueryInterface (36456) 0000CDC8 System.@IntfCast (35825) 001FBAF9 OtlTaskControl.TOmniTask.Execute (1277) 001F18F6 OtlThreadPool.TOTPWorkerThread.ExecuteWorkItem (662)
Any idea?
Additional informations
The http server is created this way : Server := TSQLHttpServer.Create('8080', [Database], '+', useHttpApiRegisteringURI);
The appplication is started with Administrator rights.
I doesn't get the message "Impossible to register URL". So, I suppose the server uses the http.sys.
mORMotNightlyBuild 2014-06-29
Delphi XE6
TestSQL3.exe -> ok
Host configuration : i7 860 @ 2.80GHz, 16 Go, 64 bits, Win 7 Pro SP1
I try to create many clients. I use the Otl library (Parallel.Async). I launch 50 clients per application. And I launch this application several times. With 600 clients there are no problem. When I reach approximatively 800 clients, I get this kind of error on many clients :
20140630 09142417 EXC EWinHTTP ("winhttp.dll error 12002 ()") at 002ABF35 PcmClient.TPcmClient.SendEventAndItsAttributes (1292) stack trace 00005A52 System.@FreeMem (4364) 000091D0 System.BeginThread (23435) 00009433 System.CharFromWChar (24252) 00009BD6 System.@LStrCat3 (26794) 0017438B mORMot.TSQLRestServerURIContext.ExecuteORMGet (25596) 0016C9BA mORMot.TSQLRest.BatchUpdate (23295) 0016FF55 mORMot.TSQLRestClientURI.EngineUpdateBlob (24283) 0017033D mORMot.TSQLRestClientURI.BatchUpdate (24348) 00005A6E System.@ReallocMem (4423) 002B1FAF PcmClients.Finalization 002B2945 PcmClients.Finalization 0019E708 IdWinsock2.Stub_select (6144) 00022BC3 System.SysUtils.AddBuf (12137) 00022C83 System.SysUtils.AddBuf (12175) 00005A6E System.@ReallocMem (4423) 00009249 System.@NewUnicodeString (23634) 000236D2 System.SysUtils.WideFormatBuf (12502)
And this king of message on the server.
20140630 09142144 EXC EHttpApiServer ("HttpSendHttpResponse failed: Une opération a été tentée sur une connexion réseau qui n’existe pas (1229)") at 00223997 SynCrtSock.EHttpApiServer.RaiseOnError (4735) stack trace 000BE6DC System.Classes.ThreadProc (14601) 00009BF6 System.ThreadWrapper (23707)
Any Idea about that?
mORMotNightlyBuild 2014-06-29
Delphi XE6
TestSQL3.exe -> ok
The /c, /Install and /Stop works well.
The service starts well when started from the services manager.
The service fails to start when launched from command line (/Start). In this case, the file httpservice.db3 is not created.
C:\Log\httpservice.exe 0.0.0.0 (2014-06-30 08:52:31)
Host=THPF-DXE4 User=rsi CPU=1*9-6-14857 OS=13.1=6.1.7601 Wow64=1 Freq=3195292
Environment variables=ALLUSERSPROFILE=C:\ProgramData APPDATA=C:\Users\rsi\AppData\Roaming CommonProgramFiles=C:\Program Files (x86)\Common Files CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files CommonProgramW6432=C:\Program Files\Common Files COMPUTERNAME=THPF-DXE4 ComSpec=C:\Windows\system32\cmd.exe FP_NO_HOST_CHECK=NO HOMEDRIVE=C: HOMEPATH=\Users\rsi LOCALAPPDATA=C:\Users\rsi\AppData\Local LOGONSERVER=\\THPF-DXE4 NUMBER_OF_PROCESSORS=1 OS=Windows_NT Path=C:\Program Files (x86)\Embarcadero\Studio\14.0\bin;C:\Users\Public\Documents\Embarcadero\Studio\14.0\Bpl;C:\Program Files (x86)\Embarcadero\Studio\14.0\bin64;C:\Users\Public\Documents\Embarcadero\Studio\14.0\Bpl\Win64;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\ PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC PROCESSOR_ARCHITECTURE=x86 PROCESSOR_ARCHITEW6432=AMD64 PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 58 Stepping 9, GenuineIntel PROCESSOR_LEVEL=6 PROCESSOR_REVISION=3a09 ProgramData=C:\ProgramData ProgramFiles=C:\Program Files (x86) ProgramFiles(x86)=C:\Program Files (x86) ProgramW6432=C:\Program Files PROMPT=$P$G PSModulePath=C:\Windows\system32\WindowsPowerShell\v1.0\Modules\ PUBLIC=C:\Users\Public SESSIONNAME=Console SystemDrive=C: SystemRoot=C:\Windows TEMP=C:\Users\rsi\AppData\Local\Temp TMP=C:\Users\rsi\AppData\Local\Temp USERDOMAIN=THPF-DXE4 USERNAME=rsi USERPROFILE=C:\Users\rsi VS120COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\ windir=C:\Windows windows_tracing_flags=3 windows_tracing_logfile=C:\BVTBin\Tests\installpackage\csilogfile.log
TSQLLog 1.18 2014-06-30T08:58:49
20140630 08584904 trace mORMotHttpServerService="ssStopped"
20140630 08584904 info Controling mORMotHttpServerService with command "/start"
20140630 08584907 OSERR TServiceController(0078DB80) Start "Le service n’a pas répondu assez vite à la demande de lancement ou de contrôle" (1053) stack trace API 00525E7A 005A15E2 005A17A6 006290EF 0062DCE6 75E7338A 77829F72 77829F45
20140630 08584907 trace Quitting command line
20140630 08584907 trace mORMotHttpServerService="ssStopped"
The example "12 - SynDB Explorer" fails to compile.
The error is:
[dcc32 Erreur] SynDBExplorerMain.pas(231): E2035 Pas assez de paramètres originaux
if C<>nil then
with TRecordEditForm.Create(self) do
try
C.Password := Crypt(C.Password);
SetRecord(nil,C,nil,nil,sConnectionHints,0,msg);
if ShowModal=mrOk then begin
C.Password := Crypt(C.Password);
if TryConnect(C,true) and (res=100) then
--> Conns.AddOne(C,false) else
if res=100 then
FreeAndNil(C);
Perfect. It works fine now. Thanks a lot.
For example the final version of my HTML/mustache below.
This code displays the connected and not connected users with different colors.
<BODY LANG="fr-FR" BGCOLOR="#ffffdd" DIR="LTR">
<P STYLE="font-weight: normal">
<FONT FACE="Arial, sans-serif" SIZE=4">
{{#users}}
{{#Connected}}<FONT COLOR="#663300">{{/Connected}}
{{^Connected}}<FONT COLOR="#ccccaa">{{/Connected}}
- {{Name}} {{Firstname}}<BR>
<FONT>
{{/users}}
</FONT>
</P>
</BODY>
Thank you for the fast correction.
It's better. But ...
This HTML/mustache
{{#users}}
{{#Connected}}
- {{Name}} {{Firstname}} ({{Connected}})<BR>
{{/Connected}}
{{/users}}
Renders:
- Sacquet Frodon (true)
- Brandebouc Meriadoc (true)
But this HTML/mustache (inverted section)
{{#users}}
{{^Connected}}
- {{Name}} {{Firstname}} ({{Connected}})<BR>
{{/Connected}}
{{/users}}
Renders nothing.
Hello,
I tried to use mustache to render html output. Below the code and the tries (I'm a beginner with mORMot, all reviews concerning the code are welcome).
The code :
procedure TSQLCarpeRestServerDB.Users(Ctxt: TSQLRestServerURIContext);
var
Rec: TSQLUser;
aUser: TSQLUser;
JSON: TStringStream;
OutputFormat: RawUTF8;
oFormat: TOutputFormat;
Mustache: TSynMustache;
Html: TStringList;
s: RawUTF8;
begin
oFormat := ofHtml;
if UrlDecodeNeedParameters(Ctxt.Parameters, 'FORMAT') then
if Ctxt.Parameters <> nil then
begin
UrlDecodeValue(Ctxt.Parameters, 'FORMAT=', OutputFormat);
oFormat := TOutputFormat(GetEnumValue(TypeInfo(TOutputFormat), 'of' + OutputFormat));
end;
aUser := TSQLUser.CreateAndFillPrepare(Self, '', []);
try
case oFormat of
ofHtml, ofJson:
begin
JSON := TStringStream.Create;
try
while aUser.FillOne do
begin
JSON.Clear;
aUser.GetJSONValues(JSON, True, True, soSelect);
JSON.Seek(0, soBeginning);
if Length(s) > 0 then
s := s + ',' + JSON.ReadString(MaxInt)
else
s := JSON.ReadString(MaxInt)
end;
s := '{"users":[' + s + ']}';
if oFormat = ofHtml then
begin
Html := TStringList.Create;
try
Html.LoadFromFile(ResourcePath + 'Users.html');
mustache := TSynMustache.Parse(Html.Text);
Ctxt.Returns(mustache.RenderJSON(s), HTML_SUCCESS, HTML_CONTENT_TYPE_HEADER);
finally
Html.Free;
end;
end
else
Ctxt.Returns(s, HTML_SUCCESS, JSON_CONTENT_TYPE_HEADER);
finally
JSON.Free;
end;
end;
ofText:
begin
try
while aUser.FillOne do
s := s + aUser.FirstName + #9 + aUser.Name + IIFStr(aUser.Connected, #9'Connected', '') + #10;
Ctxt.Returns(s, HTML_SUCCESS, TEXT_CONTENT_TYPE_HEADER);
finally
JSON.Free;
end;
end;
end;
finally
aUser.Free;
end;
end;
The JSON output (http://localhost:8080/Carpe/Users?format=json)
{
"users":
[
{"RowID":1,"Login":"safr","Firstname":"Frodon","Name":"Sacquet","Alias":"safr","Connected":true,"Resto":0},
{"RowID":2,"Login":"saga","Firstname":"Samsagace","Name":"Gamegie","Alias":"saga","Connected":false,"Resto":0},
{"RowID":3,"Login":"peto","Firstname":"Peregrin","Name":"Touque","Alias":"peto","Connected":false,"Resto":0},
{"RowID":4,"Login":"mebr","Firstname":"Meriadoc","Name":"Brandebouc","Alias":"mebr","Connected":true,"Resto":0}
]
}
As we can see, there are two connected users.
First I use the html model below (http://localhost:8080/Carpe/Users?format=html)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
<TITLE>Carpe - Users</TITLE>
</HEAD>
<BODY LANG="fr-FR" BGCOLOR="#ffffcc" DIR="LTR">
<P STYLE="font-weight: normal">
<FONT FACE="Arial, sans-serif" SIZE=4 COLOR="#663300">
{{#users}}
- {{Name}} {{Firstname}} ({{Connected}})<BR>
{{/users}}
</FONT>
</P>
</BODY>
</HTML>
The result :
- Sacquet Frodon (true)
- Gamegie Samsagace (false)
- Touque Peregrin (false)
- Brandebouc Meriadoc (true)
All right.
Second try with this html model :
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
<TITLE>Carpe - Users</TITLE>
</HEAD>
<BODY LANG="fr-FR" BGCOLOR="#ffffcc" DIR="LTR">
<P STYLE="font-weight: normal">
<FONT FACE="Arial, sans-serif" SIZE=4 COLOR="#663300">
{{#users}}
{{#Connected}}
- {{Name}} {{Firstname}} ({{Connected}})<BR>
{{/Connected}}
{{/users}}
</FONT>
</P>
</BODY>
</HTML>
The result:
- Sacquet Frodon (true)
Only the first user is rendered.
Actually, when I try the example from the SAD document § 7.3.2.2. I have the result :
Colors
red
The list is empty.
Instead of :
Colors
red
green
blue
The list is empty.
An explanation? Is there an error in the code, the HTML, the JSON?
Thanks in advance for the help.
Pages: 1