You are not logged in.
Hi,
I have TSQLRecord with Image property. I need save an image from TImage component to database then I need load it from database and show it on TImage. To save the image I use this function:
var
ClientRecord: TSQLClientiRecord;
doc: RawByteString;
pic: TSynPicture;
stream: TMemoryStream;
...
...
...
pic := TSynPicture.Create;
try
ImageDoc.Picture.Bitmap.SaveToStream(stream);
pic.LoadFromStream(stream);
if not pic.Empty then
begin
SaveAsRawByteString(pic,doc,gptJPG,80,300);
ClientRecord.Documento := doc;
end
else
begin
ClientRecord.Documento := '';
end;
finally
Pic.Free;
end;
...
...
...
However I have an error when I try to call Database.Add(ClientRecord, true) function.
Can you help me with a fast function to load and save an TImage image?
thanks
Last edited by array81 (2010-12-13 17:13:09)
Offline
See http://synopse.info/forum/viewtopic.php?pid=940#p940 about how to embed data/files in records.
See the MainDemo sample: there is a field storing a picture inside all records.
TSQLMemo = class(TSQLFile)
public
fContent: RawUTF8;
published
property Name: RawUTF8 read fName write fName;
property Created: TTimeLog read fCreated write fCreated;
property Modified: TTimeLog read fModified write fModified;
property Picture: TSQLRawBlob read fPicture write fPicture;
property Content: RawUTF8 read fContent write fContent;
property KeyWords: RawUTF8 read fKeyWords write fKeyWords;
property SignatureTime: TTimeLog read fSignatureTime write fSignatureTime;
property Signature: RawUTF8 read fSignature write fSignature;
end;
Then in FileMain.pas, here is how the picture is stored in the database:
procedure TMainForm.ActionClick(Sender: TObject;
const RecordClass: TSQLRecordClass; ActionValue: integer);
(...)
faCreate:
if ((RecordClass=TSQLData) or (RecordClass=TSQLSafeData)) then
if Open then begin
Rec.fName := S2U(ExtractFileName(FN));
if RecordClass=TSQLData then
with TSQLData(Rec) do begin
Data := StringFromFile(FN);
if TSynPicture.IsPicture(FN)<>nil then
EditForm.LoadPicture(FN,RawByteString(fPicture));
end else
with TSQLSafeData(Rec) do begin
fData := StringFromFile(FN);
if not Cypher(CaptionName,fData,true) then
exit;
end;
end else
exit;
(...)
This called the TEditForm.LoadPicture method from FileEdit.pas unit:
function TEditForm.LoadPicture(const FileName: TFileName; var Picture: RawByteString): boolean;
var Pic: TSynPicture;
begin
result := false;
if not FileExists(FileName) then
exit;
Pic := TSynPicture.Create;
try
Pic.LoadFromFile(FileName);
if Pic.Empty then
exit;
SaveAsRawByteString(Pic,Picture,gptJPG,80,300);
result := true;
finally
Pic.Free;
end;
end;
Offline
Yes, I just see your main demo but it's very confused for me (I'm not a expert), so I cannot extract a simple code to save/load an image or a file
Offline
Here are the basic steps:
1) define the Picture as such a property in a TSQLRecord descendant:
property Picture: TSQLRawBlob read fPicture write fPicture;
2) handle this Blob field with RetrieveBlob() and UpdateBlob() methods
3) Use SaveAsRawByteString() to transform a TPicture into a TSQLRawBlob
4) See the PictureToBitmap() function in FileClient.pas to guess how to create a TPicture from a TSQLRawBlob
Offline
I have this code:
1) Define my TSQLRecord:
TSQLClientsRecord = class(TSQLRecord)
private
fname: RawUTF8;
fdate: TDateTime;
fpicture: TSQLRawBlob;
published
property Name: RawUTF8 read fnamewrite fname;
property Date: TDateTime read fdatewrite fdate;
property Picture: TSQLRawBlob read fpicture write fpicture;
end;
2) Write new record on my database:
var
ClientsRecord: TSQLClientsRecord;
pic: RawByteString;
begin
ClientsRecord := TSQLClientsRecord.Create;
try
ClientsRecord.Name:= StringToUTF8(edtName.Text);
ClientsRecord.Date:= edtDate.Date;
SaveAsRawByteString(ImageClient.Picture, pic, gptJPG, 80, 300);
ClientsRecord.Picture := pic;
if Database.Add(ClientRecord, true) = 0 then
begin
MessageBox(0, 'Problems!', 'Try', MB_OK + MB_ICONSTOP);
end
finally
ClientsRecord.Free;
end;
end;
This code don't work, I think the problem is ClientsRecord.Picture := pic; because I have read on your documentation that ADD method "the BLOB fields values are not set by this method, to preserve bandwidth".
So I have try this code:
var
ClientsRecord: TSQLClientsRecord;
pic: RawByteString;
begin
ClientsRecord := TSQLClientsRecord.Create;
try
ClientsRecord.Name:= StringToUTF8(edtName.Text);
ClientsRecord.Date:= edtDate.Date;
// I have removed TSQLRawBlob field
if Database.Add(ClientRecord, true) = 0 then
begin
MessageBox(0, 'Problems!', 'Try', MB_OK + MB_ICONSTOP);
end
finally
ClientsRecord.Free;
end;
end;
to update all the fields except TSQLRawBlob (and use UpdateBlob() after) but in this way I have another problem I thinks because my TSQLClientsRecord have the Picture property and this is not define before call Database.Add.
I think this is my problem, I have understand how use TSQLRecord when I can update or add all fields of records but in my case I cannot do it.
Any idea?
Thanks for your help.
Offline
You can either use:
var
ClientsRecord: TSQLClientsRecord;
pic: RawByteString;
begin
SaveAsRawByteString(ImageClient.Picture, pic, gptJPG, 80, 300);
ClientsRecord := TSQLClientsRecord.Create;
try
ClientsRecord.Name:= StringToUTF8(edtName.Text);
ClientsRecord.Date:= edtDate.Date;
if (Database.Add(ClientRecord, true) = 0) or
not Database.UpdateBlob(TSQLClientsRecord,ClientRecord.ID,'Picture',pic) then
MessageBox(0, 'Problems!', 'Try', MB_OK + MB_ICONSTOP);
finally
ClientsRecord.Free;
end;
end;
Either (works only if Database inherits from TSQLRestClientURI):
var
ClientsRecord: TSQLClientsRecord;
pic: RawByteString;
begin
SaveAsRawByteString(ImageClient.Picture, pic, gptJPG, 80, 300);
ClientsRecord := TSQLClientsRecord.Create;
try
ClientsRecord.Name:= StringToUTF8(edtName.Text);
ClientsRecord.Date:= edtDate.Date;
ClientsRecord.Picture := pic;
if (Database.Add(ClientRecord, true) = 0) or
not Database.UpdateBlobFields(ClientRecord) then
MessageBox(0, 'Problems!', 'Try', MB_OK + MB_ICONSTOP);
finally
ClientsRecord.Free;
end;
end;
Either (works only if Database inherits from TSQLRestClientURI):
1. when you initialize your Database:
DataBase := ....Create(....);
DataBase.ForceBlobTransfert := true;
2. Then you can set the Picture property, and just call Add():
var
ClientsRecord: TSQLClientsRecord;
pic: RawByteString;
begin
SaveAsRawByteString(ImageClient.Picture, pic, gptJPG, 80, 300);
ClientsRecord := TSQLClientsRecord.Create;
try
ClientsRecord.Name:= StringToUTF8(edtName.Text);
ClientsRecord.Date:= edtDate.Date;
ClientsRecord.Picture := pic;
if (Database.Add(ClientRecord, true) = 0) then
MessageBox(0, 'Problems!', 'Try', MB_OK + MB_ICONSTOP);
finally
ClientsRecord.Free;
end;
end;
Offline
Thanks, the first code works very well. But I have another question: I'm develop a small application, the user can choose if use it as standalone application with a local file as database or use it as client/server application by LAN (the client use a file database on server).
So I need of a Database class that support both two of database (local file and client/server with database file on server). Do you have any advice about it?
Offline
Define your Database as
Database: TSQLRestClient;
Then, when you create the Database instance, use either:
- TSQLRestClientDB for local file access;
- a TSQLRestClientURI child, depending on the communication protocol used for Client/Server access, i.e. either TSQLRestClientURIMessage, TSQLRestClientURINamedPipe or TSQLite3HttpClient. I would recommend using TSQLite3HttpClient for easy network handling (GDI messages are not transmitted over the network, and Named Pipes have some security issue with Vista/Seven version of Windows).
But you'll also have to write a Server application, relying on a TSQLRestServerDB instance.
The whole code could be the same for the client, either with local direct access or remote access via the network, depending on the exact class of the Database instance created.
Offline
Thanks I will try. Thanks again.
Offline
Another think. I like create only an application. The user can use it as: 1) Standalone application (with local database), 2) Client/Server application by LAN (with database file on server).
In case 2) the same application can works as client (on client computer) and as server (on server computer).
Is't possible with only a database class (without change the code from standalone, client ot server)?
Offline
It's perfectly possible to have the same application running as stand-alone, client or server. It does make sense, because the same code will be share for the three way of running.
The way your application is behaving will depend on the TSQLRest class instances created.
- a TSQLRestClientDB for the stand-alone mode;
- a TSQLite3HttpServer for the server mode;
- a TSQLite3HttpClient for the client mode.
Offline
I'm working to create my application. I need of application that can work as Standalone, Client or Server (the user can choose if use as standalone application or Client/Server application, in this case he can choose if use it as client or server). Until now I have develop my application as standalone application only, now I want add client/server support.
In your last post you have told me:
The way your application is behaving will depend on the TSQLRest class instances created.
- a TSQLRestClientDB for the stand-alone mode;
- a TSQLite3HttpServer for the server mode;
- a TSQLite3HttpClient for the client mode.
So I have write this code:
var
Server: TSQLite3HttpServer;
Database: TSQLRest;
Model: TSQLModel;
// STANDALONE APPLICATION
procedure TMainForm.LoadLocalDatabase(Filename: string; Overwrite: Boolean);
begin
if FileExists(Filename) then
begin
if Overwrite then
begin
DeleteFile(Filename);
end;
end;
if Model <> nil then
Model.Free;
if Database <> nil then
Database.Free;
Model := TSQLModel.Create([TSQLContatti, TSQLProgetti, TSQLProgettiClienti, TSQLProgettiUtenti, TSQLProgettiAttivita, TSQLProgettiFlussi, TSQLProgettiDocumenti, TSQLProgettiFatture, TSQLProgettiFSS]);
Database := TSQLRestClientDB.Create(Model, nil, Filename, TSQLRestServerDB);
TSQLRestServerDB(TSQLRestClientDB(Database).Server).CreateMissingTables(0);
end;
// CLIENT/SERVER APPLICATION (CLIENT)
procedure TMainForm.LoadClientDatabase(Server: string; Port: Integer);
begin
if Model <> nil then
Model.Free;
if Database <> nil then
Database.Free;
Model := TSQLModel.Create([TSQLContatti, TSQLProgetti, TSQLProgettiClienti, TSQLProgettiUtenti, TSQLProgettiAttivita, TSQLProgettiFlussi, TSQLProgettiDocumenti, TSQLProgettiFatture, TSQLProgettiFSS]);
Database := TSQLite3HttpClient.Create(Server, IntToStr(Port), Model);
TSQLRestServerDB(TSQLRestClientDB(Database).Server).CreateMissingTables(0);
end;
// CLIENT/SERVER APPLICATION (SERVER)
procedure TMainForm.LoadServerDatabase(Port: Integer; Filename: string; Overwrite: Boolean);
begin
if FileExists(Filename) then
begin
if Overwrite then
begin
DeleteFile(Filename);
end;
end;
if Model <> nil then
Model.Free;
if Database <> nil then
Database.Free;
if Server <> nil then
Server.Free;
Model := TSQLModel.Create([TSQLContatti, TSQLProgetti, TSQLProgettiClienti, TSQLProgettiUtenti, TSQLProgettiAttivita, TSQLProgettiFlussi, TSQLProgettiDocumenti, TSQLProgettiFatture, TSQLProgettiFSS]);
Database := TSQLRestServerDB.Create(Model, Filename);
Database.CreateMissingTables(0);
Server := TSQLite3HttpServer.Create(IntToStr(Port), DB);
end;
Is this code right? I have some problem with my "standalone" code, for example Database.ExecuteList and Database.EngineExecute are not found. With only "standalone" application I used:
var
Database: TSQLRestClient;
but now I need use
var
Database: TSQLRest;
So I think there is an error on my code. Can you help me?
NOTE: when my application works as server must be a server for other clients application but I need also use it as standalone application (on server computer). I hope you understand it.
Last edited by array81 (2011-01-23 22:59:37)
Offline
All business logic must be made on the server side only.
For example, CreateMissingTable must be called in the server or the standalone application only.
You should therefore make a difference between server or standalone on one part, and client on the other part.
Your Database should be indeed declared as Database: TSQLRestClient.
For the client, use a dedicated ServerDatabase: TSQLRestServerDB instance.
Then for the standalone, use the
On server computer, you need to launch a client, instead of a standalone application.
If both standalone and server applications access the DB file at the same time, there could be some concurrency race problems. I understand than you close the server before running the stand alone version... but perhaps launching the client could be better.
The stand-alone application could make sense only in case of debugging, or as a "demo" version.
And as I wrote in the main demo presentation article, use a common function to create the TSQLModel.
So you'll have less duplicated code, and your app will be less error prone.
Offline
I hope I have uderstand. What do you think about this new code (only LoadServerDatabase us different):
var
Server: TSQLite3HttpServer;
Database: TSQLRestClient;
DatabaseServer: TSQLRestServerDB;
Model: TSQLModel;
procedure TMainForm.LoadServerDatabase(Port: Integer; Filename: string; Overwrite: Boolean);
begin
if FileExists(Filename) then
begin
if Overwrite then
begin
DeleteFile(Filename);
end;
end;
if Model <> nil then
Model.Free;
if Database <> nil then
Database.Free;
if DatabaseServer <> nil then
DatabaseServer.Free;
if Server <> nil then
Server.Free;
Model := TSQLModel.Create([TSQLContatti, TSQLProgetti, TSQLProgettiClienti, TSQLProgettiUtenti, TSQLProgettiAttivita, TSQLProgettiFlussi, TSQLProgettiDocumenti, TSQLProgettiFatture, TSQLProgettiFSS]);
DatabaseServer := TSQLRestServerDB.Create(Model, Filename);
if DatabaseServer <> nil then
begin
DatabaseServer.CreateMissingTables(0);
Server := TSQLite3HttpServer.Create(IntToStr(Port), DatabaseServer);
end;
Database := TSQLRestClientDB.Create(Model, nil, Filename, TSQLRestServerDB);
if Database <> nil then
begin
TSQLRestServerDB(TSQLRestClientDB(Database).Server).CreateMissingTables(0);
end;
end;
In this way when my application works as server have 2 Database access (is it a problem?): Database as standalone application and DatabaseServer as server.
What are "concurrency race problems"? It is only a small decrease in performance or stability problem.
I think I just "use a common function to create the TSQLModel" or I don't undestand what you mean.
Offline
About TSQLModel:
function GetDatabaseModel: TSQLModel;
begin
result := TSQLModel.Create([TSQLContatti, TSQLProgetti, TSQLProgettiClienti, TSQLProgettiUtenti, TSQLProgettiAttivita, TSQLProgettiFlussi, TSQLProgettiDocumenti, TSQLProgettiFatture, TSQLProgettiFSS]);
end;
(...)
Model := GetDatabaseModel;
(...)
It doesn't make sense to test for DatabaseServer<>nil or Database<>nil after a Create method call: by design (like any other Delphi class), it will create an instance, so it will never be nil. In case of an error, it will raise an exception.
So you should put a try..except block to catch any error, and don't check for nil.
Why are you creating a TSQLRestServerDB then a TSQLRestClientDB instance in your code?
You shouldn't. It will create TWO TSQLRestServerDB instances at the same time...
And you're still calling CreateMissingTable two times...
So you should have better written:
try
Model := GetDatabaseModel;
Database := TSQLRestClientDB.Create(Model, nil, Filename, TSQLRestServerDB);
DatabaseServer := TSQLRestClientDB(Database).Server;
DatabaseServer.CreateMissingTables(0);
Server := TSQLite3HttpServer.Create(IntToStr(Port), DatabaseServer);
except
on E: Exception do
// handle initialization error here
end;
You could also have created your own TSQLRestServerDB child, calling CreateMissingTables and running a TSQLite3HttpServer instance directly.
This is the way I use it normally: in fact, having its own TSQLRestServerDB descendant allow to put all your business logic (i.e. all that should be done server-side) implemented in a dedicated class, with full direct access to the SQL engine.
And you can even create multiple instance of the same server, at the same time, if you want, to access multiple database files for example.
It's always better for your application architecture to make all your logic in classes, with properties, instead of using globals.
Offline
Thanks it works. I have only a problem of "SPEED" when use client/server by my LAN (my LAN use Windows XP and Windows 7 computers).
My TEST database is only 500 (each tables have only 2/3 rows) kb but when my client need read/write data from server need of 4/5 seconds. (on standalone mode <1 second)
Is it normal? Do you have some suggestions?
I will check to SQL code but I don't think I will found much unnecessary code.
Last edited by array81 (2011-01-26 08:29:32)
Offline
Do you use:
DataBase.ForceBlobTransfert := true;
?
In this case, this could be the problem: all pictures are retrieved when you get all records in any FillPrepare() loop, for instance.
Locally, it's not a problem, but over the network, your 100Mb or 1Gb link is not big enough!
So the solution is to let ForceBlobTransfert to false, then use explicit RetrieveBlob() method calls to get the picture data.
Offline
NO. I use alway RetrieveBlob() when I need of it.
I have a mainform that other 2 form (project and users).
On Clients form I use this piece of code to show data of select user:
ContattoRecord := TSQLContatti.Create(Database,'ID="%"',[IntToStr(EditItem)]);
Database.RetrieveBlob(TSQLContatti, ContattoRecord.ID, 'Documento', doc);
ContattoRecord.Documento := doc;
Database.RetrieveBlob(TSQLContatti, ContattoRecord.ID, 'FatLogo', doc);
ContattoRecord.FatLogo := doc;
Database.RetrieveBlob(TSQLContatti, ContattoRecord.ID, 'FatIntestazioneUtente', ms);
Note: I have 3 test client, only for 1 client I have set 'Documento', 'FatLogo', 'FatIntestazioneUtente' but I have the some problem with all them (read/write lag about 2/3 secons).
In Project form I use about 10 code like this:
TavolaUtenti := Database.ExecuteList([], 'SELECT Contatti.ID, Contatti.IntNome, ProgettiUtenti.ID FROM Contatti LEFT JOIN ProgettiUtenti ON ProgettiUtenti.IDUtente=Contatti.ID WHERE ProgettiUtenti.IDProgetto="' + IntToStr(EditItem) + '" ORDER BY Contatti.IntNome');
To read the data (lag 2/3 seconds) and about 5 code as these:
for e := 0 to grdAttivita.RowCount - 1 do
begin
if (grdAttivita.Cell[3, e].AsString = '') or
(grdAttivita.Cell[4, e].AsString = '') then
Continue;
ProgettoAttivitaRecord := TSQLProgettiAttivita.Create;
try
ProgettoAttivitaRecord.IDProgetto := EditItem;
if grdAttivita.Cell[4, e].AsString <> '' then
ProgettoAttivitaRecord.IDUtente := IDUtenti.Counter[IDUtenti.IndexOf(grdAttivita.Cell[4, e].AsString)];
ProgettoAttivitaRecord.Stato := grdAttivita.Cell[2, e].AsInteger;
ProgettoAttivitaRecord.Oggetto := StringToUTF8(grdAttivita.Cell[3, e].AsString);
ProgettoAttivitaRecord.Data := grdAttivita.Cell[5, e].AsDateTime;
ProgettoAttivitaRecord.ID := grdAttivita.Cell[0, e].AsInteger;
if grdAttivita.Cell[0, e].AsString = '' then
begin
if Database.Add(ProgettoAttivitaRecord, true) = 0 then
begin
ErrorDB := True;
end;
end
else
begin
ProgettoAttivitaRecord.ID := grdAttivita.Cell[0, e].AsInteger;
if not Database.Update(ProgettoAttivitaRecord) then
begin
ErrorDB := True;
end;
end;
finally
ProgettoAttivitaRecord.Free;
end;
end;
to save the data (lag about 4/5 seconds). As standalone application I don't have any problems.
Offline
You should use a transaction to speed up writing.
Database.BeginTransaction;
try
/// add some records
finally
Database.Commit;
end;
And did you try your client application on the same computer than the server?
How are you creating the client classes?
What is your antivirus software? Did you try turning http inspection off?
Offline
And did you try your client application on the same computer than the server?
No I did, I have tested my application in 2 computers (one for client and one for server). I have made my test in 2 different LAN: one LAN with 3 computers (all Windows 7) and one LAN with 7 computers (all Windows XP Professional).
How are you creating the client classes?
I'm not sure I'm undestand your question. I have used this code:
var
Server: TSQLite3HttpServer;
Database: TSQLRestClient;
DatabaseServer: TSQLRestServerDB;
// STANDALONE APPLICATION
procedure TMainForm.LoadLocalDatabase(Filename: string; Overwrite: Boolean);
begin
if FileExists(Filename) then
begin
if Overwrite then
begin
DeleteFile(Filename);
end;
end;
if Database <> nil then
Database.Free;
try
Database := TSQLRestClientDB.Create(Model, nil, Filename, TSQLRestServerDB);
TSQLRestServerDB(TSQLRestClientDB(Database).Server).CreateMissingTables(0);
LoadData();
except
//on E: Exception do
// handle initialization error here
end;
end;
// CLIENT/SERVER APPLICATION (CLIENT)
procedure TMainForm.LoadClientDatabase(Server: string; Port: Integer);
begin
if Database <> nil then
Database.Free;
try
Database := TSQLite3HttpClient.Create(Server, IntToStr(Port), Model);
LoadData();
except
//on E: Exception do
// handle initialization error here
end;
end;
// CLIENT/SERVER APPLICATION (SERVER)
procedure TMainForm.LoadServerDatabase(Port: Integer; Filename: string; Overwrite: Boolean);
begin
if FileExists(Filename) then
begin
if Overwrite then
begin
DeleteFile(Filename);
end;
end;
if Database <> nil then
Database.Free;
try
Database := TSQLRestClientDB.Create(Model, nil, Filename, TSQLRestServerDB);
DatabaseServer := TSQLRestClientDB(Database).Server;
DatabaseServer.CreateMissingTables(0);
Server := TSQLite3HttpServer.Create(IntToStr(Port), DatabaseServer);
LoadData;
except
//on E: Exception do
// handle initialization error here
end;
end;
I use LoadData() function to load the data from database and put them on a grid. Note: I use "Model := GetDatabaseModel;" when mainform is create.
What is your antivirus software?
In all computers there is Microsoft Essential Security and Windows Firewall.
Did you try turning http inspection off?
I don't have found this option on Microsoft Essential Security.
You should use a transaction to speed up writing. (Database.BeginTransaction;)
When I need write many data I need use Database.BeginTransaction; Is it right? I will tried it.
Thanks, other suggestions are welcome.
Offline
I have check the framework code but I cannot found BeginTransaction function for database object...
I think I don't understand your last post.
Offline
I have check the framework code but I cannot found BeginTransaction function for database object...
I think I don't understand your last post.
when on client user add more records or update more records ,the table is locked,other user can't get records.
in this Framework
database.Transactionbegin(TSQLTableclass)
beginTransaction is in order to inform the Table to do something
commitTransaction is in order to ENd your opening the table,
in this Framework
Database.commit
sometimes the Rollback is used .
Last edited by longge007 (2011-01-27 04:45:31)
Offline
So I need use a code like this:
database.Transactionbegin(TSQLProgettoAttivita)
try
if grdAttivita.Cell[0, e].AsString = '' then
begin
if Database.Add(ProgettoAttivitaRecord, true) = 0 then
begin
ErrorDB := True;
end;
end
else
begin
ProgettoAttivitaRecord.ID := grdAttivita.Cell[0, e].AsInteger;
if not Database.Update(ProgettoAttivitaRecord) then
begin
ErrorDB := True;
end;
end;
finally
Database.commit
end;
right?
Offline
OK, I have 2 questions:
1) Do I need use Transactionbegin also when I use Dtabase.Delete(...) function?
2) When I have more pieces of code like my last post I need Transactionbegin only one time (and I put all my code inside try...finally) or I need use Transactionbegin one time for each piace?
I have add Transactionbegin in all my code but the result is the same. When I use my application as standalone all works, when I use as client/server (I use 2 different computers) all works but with this horrible lag (between 2-5 seconds).
Other suggestions are welcome.
Thanks
PS if you want (and you tell me how) I can send you 2 small SWF video of standalone and client application to see the lag.
Last edited by array81 (2011-01-27 16:27:27)
Offline
Transactions are a standard SQL feature.
They will speed up data modification: update, insert or delete.
About the client speed, I guess you're running a lot of requests during your queries.
What is your network traffic generated by the applications?
Use ProcessExplorer to retrieve more info.
What are the info that your browser displayed when you enter this URI:
http://localhost:8080/root/stat
here, 8080 is the port number of your server, root is the URI root (by default), and stat is a standard service retrieving some statistics.
A typical response is:
Clients now=1 max=2
Data in=352 B out=963 B
Requests=6 Updates=0 Invalid=6
Time spent in requests = 200us
Offline
OK I have make some test about my application. I have used a HTTP traffic analizer to know the real traffic of my application.
TEST
I have started Server and Client application then I have connect Client with Server, after this I have only open a windows and retrive some data (only readb data) from database.
RESULT
Result of my HTTP traffic analizer: 12.57 kB in 6.79 seconds. 6.79 seconds!!!
Reselt of http://localhost:8080/root/stat
Clients now=1 max=1
Data in=5784 B out=3969 B
Requests=27 Updates=0 Invalid=0
Time spent in requests = 26.41ms
This is HTTP traffic analizer log:
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 92
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 92
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT Contatti.ID, Contatti.IntNome, Contatti.Ruolo FROM Contatti ORDER BY Contatti.IntNome
HTTP/1.1 400 OK
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 39
Content-Type: text/html
Connection: Keep-Alive
TSQLite3HttpServer Server Error 400<hr>HTTP/1.0 404 OK
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 39
Content-Type: text/html
TSQLite3HttpServer Server Error 404<hr>
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 44
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 44
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT * FROM Progetti WHERE ID="1" LIMIT 1;
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 192
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=8,"Values"=["Descrizione","ID","Oggetto","Tipo","Fascicolo","DataInizio","DataFine","Stato",null,1,"prova","Accatastamento","123","2011-01-19T13:22:44","2011-01-19T13:22:44",0]}
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 196
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT Contatti.ID, Contatti.IntNome, Contatti.Ruolo FROM Contatti LEFT JOIN ProgettiClienti ON ProgettiClienti.IDCliente=Contatti.ID WHERE ProgettiClienti.IDProgetto="1" ORDER BY Contatti.IntNome
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 71
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=3,"Values"=["ID","IntNome","Ruolo",3,"Burbi Massimo",0]}
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 192
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT Contatti.ID, Contatti.IntNome, Contatti.Ruolo FROM Contatti LEFT JOIN ProgettiUtenti ON ProgettiUtenti.IDUtente=Contatti.ID WHERE ProgettiUtenti.IDProgetto="1" ORDER BY Contatti.IntNome
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 71
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=3,"Values"=["ID","IntNome","Ruolo",2,"Burbi Manuela",1]}
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 310
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT Contatti.ID, Contatti.IntNome, ProgettiAttivita.ID, ProgettiAttivita.IDProgetto, ProgettiAttivita.Oggetto, ProgettiAttivita.Data, ProgettiAttivita.Stato FROM Contatti LEFT JOIN ProgettiAttivita ON ProgettiAttivita.IDUtente=Contatti.ID WHERE ProgettiAttivita.IDProgetto="1" ORDER BY ProgettiAttivita.Data
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 178
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=7,"Values"=["ID","IntNome","ID","IDProgetto","Oggetto","Data","Stato",1,"Masci Martin",2,1,"asdfaaaa","2011-01-02",1,1,"Masci Martin",1,1,"123458","2011-01-26",1]}
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 306
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT ProgettiFlussi.ID, ProgettiFlussi.IDProgetto, ProgettiFlussi.IDUtente, ProgettiFlussi.IDCliente, ProgettiFlussi.Descrizione, ProgettiFlussi.Data, ProgettiFlussi.Importo, ProgettiFlussi.IDFattura, ProgettiFlussi.IVA FROM ProgettiFlussi WHERE ProgettiFlussi.IDProgetto="1" ORDER BY ProgettiFlussi.Data
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 201
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=9,"Values"=["ID","IDProgetto","IDUtente","IDCliente","Descrizione","Data","Importo","IDFattura","IVA",1,1,2,3,"prova","2011-01-10","100",1,0,2,1,2,3,"abc1234","2011-01-25","145.36",0,0]}
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 72
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT Contatti.ID, Contatti.IntNome FROM Contatti WHERE Contatti.ID="2"
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 61
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=2,"Values"=["ID","IntNome",2,"Burbi Manuela"]}
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 72
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT Contatti.ID, Contatti.IntNome FROM Contatti WHERE Contatti.ID="3"
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 61
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=2,"Values"=["ID","IntNome",3,"Burbi Massimo"]}
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 72
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT Contatti.ID, Contatti.IntNome FROM Contatti WHERE Contatti.ID="2"
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 61
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=2,"Values"=["ID","IntNome",2,"Burbi Manuela"]}
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 72
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 72
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT Contatti.ID, Contatti.IntNome FROM Contatti WHERE Contatti.ID="3"
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 61
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=2,"Values"=["ID","IntNome",3,"Burbi Massimo"]}
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 350
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT Contatti.ID, Contatti.IntNome, ProgettiDocumenti.ID, ProgettiDocumenti.IDProgetto, ProgettiDocumenti.Descrizione, ProgettiDocumenti.Data, ProgettiDocumenti.Filename, ProgettiDocumenti.Size FROM Contatti LEFT JOIN ProgettiDocumenti ON ProgettiDocumenti.IDUtente=Contatti.ID WHERE ProgettiDocumenti.IDProgetto="1" ORDER BY ProgettiDocumenti.Data
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 100
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=8,"Values"=["ID","IntNome","ID","IDProgetto","Descrizione","Data","Filename","Size"]}
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 261
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT ProgettiFatture.ID, ProgettiFatture.IDCliente, ProgettiFatture.IDUtente, ProgettiFatture.Oggetto, ProgettiFatture.Data, ProgettiFatture.Importo, ProgettiFatture.Spese FROM ProgettiFatture WHERE ProgettiFatture.IDProgetto="1" ORDER BY ProgettiFatture.Data
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 128
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=7,"Values"=["ID","IDCliente","IDUtente","Oggetto","Data","Importo","Spese",1,0,2,"prova","2011-01-15","100","0"]}
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 98
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT Contatti.ID, Contatti.IntNome FROM Contatti WHERE Contatti.ID="2" ORDER BY Contatti.IntNome
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 61
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=2,"Values"=["ID","IntNome",2,"Burbi Manuela"]}
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 180
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT Contatti.ID, Contatti.IntNome FROM Contatti LEFT JOIN ProgettiClienti ON ProgettiClienti.IDCliente=Contatti.ID WHERE ProgettiClienti.IDProgetto="1" ORDER BY Contatti.IntNome
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 61
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=2,"Values"=["ID","IntNome",3,"Burbi Massimo"]}
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 311
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT ProgettiFatture.ID, ProgettiFatture.IDCliente, ProgettiFatture.IDUtente, ProgettiFatture.Importo, ProgettiFatture.Spese, ProgettiFatture.IVA, ProgettiFatture.CAP, ProgettiFatture.Ritenuta, ProgettiFatture.RitenutaUsa FROM ProgettiFatture WHERE ProgettiFatture.IDProgetto="1" ORDER BY ProgettiFatture.Data
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 136
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=9,"Values"=["ID","IDCliente","IDUtente","Importo","Spese","IVA","CAP","Ritenuta","RitenutaUsa",1,0,2,"100","0",20,4,2,1]}
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 196
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT Contatti.ID, Contatti.IntNome, Contatti.Ruolo FROM Contatti LEFT JOIN ProgettiClienti ON ProgettiClienti.IDCliente=Contatti.ID WHERE ProgettiClienti.IDProgetto="1" ORDER BY Contatti.IntNome
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 71
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=3,"Values"=["ID","IntNome","Ruolo",3,"Burbi Massimo",0]}
GET root HTTP/1.1
Accept: */*
Host: 192.168.1.4
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 151
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
SELECT ProgettiFlussi.Importo FROM ProgettiFlussi WHERE ProgettiFlussi.IDProgetto="1" AND ProgettiFlussi.IDCliente="3" AND ProgettiFlussi.IDFattura > 0
HTTP/1.1 200 OK
Server-InternalState: 2
X-Powered-By: SynCrtSock [url]http://synopse.info[/url]
Server: TSQLite3HttpServer
Content-Length: 44
Content-Type: application/json; charset=UTF-8
Connection: Keep-Alive
{"FieldCount"=1,"Values"=["Importo","100"]}
I don't understand where is the error/problem.
Offline
Time spent in requests = 26.41ms
There the problem is in the communication layer, not the database layer!
Did you try setting your AntiVirus off?
Use ProcessExplorer from http://technet.microsoft.com/en-us/sysi … s/bb896653 to check:
- how many threads are created on the server side;
- how many TCP/IP connections are created - there should be only one connection per client, kept alive during all handling (since there is a 20 seconds keep alive parameter value).
Offline
Other test, other result.
TEST
This time I have made the some test of last post but on my Office LAN (all computer with Windows XP, last post test on my Home LAN all computer with Windows 7).
I have disable the real time protection of Windows Essential Security (on Server and Client computer).
RESULT
Reselt of http://localhost:8080/root/stat
Clients now=1 max=1
Data in=5776 B out=3969 B
Requests=27 Updates=0 Invalid=0
Time spent in requests = 92.27ms
ProcessExplorer result:
This is my first time with ProcessExplorer so I'm sure that I have read the correct data, I have run ProcessExplorer before my application then double click on my proccess and check on threads and TCP/IP:
threads = 37 (server) 2 (client)
TCP/IP = In the list I see always 1 item that change color (green -> red)
There is always the LAG time!
Sorry for all my post but I have choose your framework because it's flexible and easy and I'd like solve this stupid problem.
Suggests?
Offline
Is your client remaining during the whole process?
I suspect that 37 threads is a bit high for the server.
Perhaps the client is reconnecting each time, which is not the expected behaviour, and can be slow...
Does the color for TCP/IP blink during the tests, or only stay green, then red when the client is finished?
Offline
When try to load my data I have these colors for TCP/IP on client application (this is the right order):
1 row white
1 row red and 1 row green (together)
1 row white
1 row red and 1 row green (together)
1 row white
I have tried to use:
{...$define USETHREADPOOL}
threads = 5 (server) 2 (client)
but there is always the LAG problem...
Offline
A) Can you check the value of the ServerConnectionCount property of your TSQLite3HttpServer instance?
B) Try these steps:
1) define DEBUG2 and DEBUG23 conditionals in SynCrtSock.pas:
interface
{$define DEBUG2}
{$define DEBUG23}
2) add a AllocConsole call in your OnCreate event of the main form (or whenever you want)
This will create some logs on a console...
Please put them here...
C) put your code in PasteBin, as I suggested above, so that I could check it...
Offline
A) After my test ServerConnectionCount = 3;
B) Is there a way to save the log from console to TXT file? In alternative I cannot put it here...
C) I have the LAG problem all time that I try to load/write data (not only on a part of my code), do you need of all source code of my project (!) or only the piece of code that I have use to make my test?
Offline
OK I have used PasteBin to send you the piece of code of my test, this is the link (valid for 1 day):
http://pastebin.mozilla.org/995142
When I open a form (on show event) I call one after the other all the functions that you find on the code.
Tell me if there is a awaty to save the log so I post it.
Offline
This code seems correct.
But the part I need is all the Client and Server logic: how you create the TSQLHttpClient instances, for instance...
I've added a new TSQLTable.GetString() method because it could help you having direct access to a property without all those UTF8ToString(TSQLTable.GetU()) calls.
Offline
A) After my test ServerConnectionCount = 3;
So you connected a client instance three times.
Is it expected? Should not be only once?
B) Is there a way to save the log from console to TXT file? In alternative I cannot put it here...
Click on the system menu box (upper left corner of the window), then select Edit / Select All.
Then press the Enter key on the keyboard.
You have all messages in the clipboard.
Just copy those messages here or in a PasteBin.
One more question: how to you refer to the server PC?
Did you use a fixed IP address?
If not, try using a fixed IP address when you create the TSQLHttpClient instance.
Offline
This is the link of Client and Server logic code: [link]http://pastebin.mozilla.org/995445[/link]
The user select how use my application the I call one of 3 function
CaricaDatabaseLocale(Filename: string; Overwrite: Boolean); // StandAlone
CaricaDatabaseClient(Server: string; Port: Integer); // Client
CaricaDatabaseServer(Port: Integer; Filename: string; Overwrite: Boolean); // Server
Server log:
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 163
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=163
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 180
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=180
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 176
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=176
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 310
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=310
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 289
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=289
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 92
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=92
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 44
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=44
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 196
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=196
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 192
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=192
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 310
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=310
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 306
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=306
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 72
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=72
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 72
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=72
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 72
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=72
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 72
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=72
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 350
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=350
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 261
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=261
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 98
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=98
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 180
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=180
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 311
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=311
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 196
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=196
THttpServerSocket.HeaderIn Accept: */*
THttpServerSocket.HeaderIn Host: 192.168.0.8
THttpServerSocket.HeaderIn User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Window
s; FREE)
THttpServerSocket.HeaderIn Content-Length: 151
THttpServerSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpServerSocket.HeaderIn Keep-Alive: 20000
THttpServerSocket.HeaderIn Connection: Keep-Alive
GetBody ContentLength=151
Client log:
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=192
GET root Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 196
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK HTTP/1.1 200 OKTHttpClientSocket.HeaderIn Server-InternalState: 1
THttpClientSocket.HeaderIn X-Powered-By: SynCrtSock http://synopse.info
THttpClientSocket.HeaderIn Server: TSQLite3HttpServer
THttpClientSocket.HeaderIn Content-Length: 71
THttpClientSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=71
GET root Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 192
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK HTTP/1.1 200 OKTHttpClientSocket.HeaderIn Server-InternalState: 1
THttpClientSocket.HeaderIn X-Powered-By: SynCrtSock http://synopse.info
THttpClientSocket.HeaderIn Server: TSQLite3HttpServer
THttpClientSocket.HeaderIn Content-Length: 71
THttpClientSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=71
GET root Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 310
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK HTTP/1.1 200 OKTHttpClientSocket.HeaderIn Server-InternalState: 1
THttpClientSocket.HeaderIn X-Powered-By: SynCrtSock http://synopse.info
THttpClientSocket.HeaderIn Server: TSQLite3HttpServer
THttpClientSocket.HeaderIn Content-Length: 178
THttpClientSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=178
GET root Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 306
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK HTTP/1.1 200 OKTHttpClientSocket.HeaderIn Server-InternalState: 1
THttpClientSocket.HeaderIn X-Powered-By: SynCrtSock http://synopse.info
THttpClientSocket.HeaderIn Server: TSQLite3HttpServer
THttpClientSocket.HeaderIn Content-Length: 201
THttpClientSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=201
GET root Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 72
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK HTTP/1.1 200 OKTHttpClientSocket.HeaderIn Server-InternalState: 1
THttpClientSocket.HeaderIn X-Powered-By: SynCrtSock http://synopse.info
THttpClientSocket.HeaderIn Server: TSQLite3HttpServer
THttpClientSocket.HeaderIn Content-Length: 61
THttpClientSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=61
GET root Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 72
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK HTTP/1.1 200 OKTHttpClientSocket.HeaderIn Server-InternalState: 1
THttpClientSocket.HeaderIn X-Powered-By: SynCrtSock http://synopse.info
THttpClientSocket.HeaderIn Server: TSQLite3HttpServer
THttpClientSocket.HeaderIn Content-Length: 61
THttpClientSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=61
GET root Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 72
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK HTTP/1.1 200 OKTHttpClientSocket.HeaderIn Server-InternalState: 1
THttpClientSocket.HeaderIn X-Powered-By: SynCrtSock http://synopse.info
THttpClientSocket.HeaderIn Server: TSQLite3HttpServer
THttpClientSocket.HeaderIn Content-Length: 61
THttpClientSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=61
GET root Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 72
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK HTTP/1.1 200 OKTHttpClientSocket.HeaderIn Server-InternalState: 1
THttpClientSocket.HeaderIn X-Powered-By: SynCrtSock http://synopse.info
THttpClientSocket.HeaderIn Server: TSQLite3HttpServer
THttpClientSocket.HeaderIn Content-Length: 61
THttpClientSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=61
GET root Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 350
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK HTTP/1.1 200 OKTHttpClientSocket.HeaderIn Server-InternalState: 1
THttpClientSocket.HeaderIn X-Powered-By: SynCrtSock http://synopse.info
THttpClientSocket.HeaderIn Server: TSQLite3HttpServer
THttpClientSocket.HeaderIn Content-Length: 100
THttpClientSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=100
GET root Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 261
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK
GET root RETRY Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 261
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK HTTP/1.1 200 OKTHttpClientSocket.HeaderIn Server-InternalState: 1
THttpClientSocket.HeaderIn X-Powered-By: SynCrtSock http://synopse.info
THttpClientSocket.HeaderIn Server: TSQLite3HttpServer
THttpClientSocket.HeaderIn Content-Length: 128
THttpClientSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=128
GET root Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 98
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK HTTP/1.1 200 OKTHttpClientSocket.HeaderIn Server-InternalState: 1
THttpClientSocket.HeaderIn X-Powered-By: SynCrtSock http://synopse.info
THttpClientSocket.HeaderIn Server: TSQLite3HttpServer
THttpClientSocket.HeaderIn Content-Length: 61
THttpClientSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=61
GET root Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 180
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK HTTP/1.1 200 OKTHttpClientSocket.HeaderIn Server-InternalState: 1
THttpClientSocket.HeaderIn X-Powered-By: SynCrtSock http://synopse.info
THttpClientSocket.HeaderIn Server: TSQLite3HttpServer
THttpClientSocket.HeaderIn Content-Length: 61
THttpClientSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=61
GET root Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 311
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK HTTP/1.1 200 OKTHttpClientSocket.HeaderIn Server-InternalState: 1
THttpClientSocket.HeaderIn X-Powered-By: SynCrtSock http://synopse.info
THttpClientSocket.HeaderIn Server: TSQLite3HttpServer
THttpClientSocket.HeaderIn Content-Length: 136
THttpClientSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=136
GET root Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 196
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK HTTP/1.1 200 OKTHttpClientSocket.HeaderIn Server-InternalState: 1
THttpClientSocket.HeaderIn X-Powered-By: SynCrtSock http://synopse.info
THttpClientSocket.HeaderIn Server: TSQLite3HttpServer
THttpClientSocket.HeaderIn Content-Length: 71
THttpClientSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=71
GET root Send
HeaderOut GET root HTTP/1.1
Accept: */*
Host: 192.168.0.8
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows; FREE)
Content-Length: 151
Content-Type: application/json; charset=UTF-8
Keep-Alive: 20000
Connection: Keep-Alive
OK HTTP/1.1 200 OKTHttpClientSocket.HeaderIn Server-InternalState: 1
THttpClientSocket.HeaderIn X-Powered-By: SynCrtSock http://synopse.info
THttpClientSocket.HeaderIn Server: TSQLite3HttpServer
THttpClientSocket.HeaderIn Content-Length: 44
THttpClientSocket.HeaderIn Content-Type: application/json; charset=UTF-8
THttpClientSocket.HeaderIn Connection: Keep-Alive
OK BodyGetBody ContentLength=44
I don't need of "ServerConnectionCount = 3" but I don't know how fix it.
A clarification about my test I always do this steps:
1) Run Application as Server;
2) Run Application as Client, read some value from database and put it on a grid; -> ServerConnectionCount = 1
3) Double click on a grid row -> A new window is open and data read from database (the code of my last post [link]http://pastebin.mozilla.org/995142[/link]) -> ServerConnectionCount = 3;
If I close this window and make a double click on row (to show the window again) -> ServerConnectionCount = 5!
On my Home LAN I use DINAMIC IP address but on my Office LAN all computer have a STATIC IP address.
I will tried TSQLTable.GetString() code.
Do you need of other information/code?
Offline
Please remove DEBUG2 and DEBUG23... there is no handy info here.
Two new ideas - perhaps B is cleaner:
A) Can you run the server in a remote PC, then launch your client program in the Delphi IDE?
Then could you step in the methods from http://pastebin.mozilla.org/995142 using F8 to see if ExecuteList are indeed slow....
B) Could you use a GetTickCount, to make a rough estimation of the speed.
For example, hack SQLite3HttpClient.pas unit with this:
function TSQLite3HttpClient.URI(const url, method: RawUTF8; Resp, Head,
SendData: PRawUTF8): Int64Rec;
var H,S: RawUTF8;
tix: cardinal;
begin
tix := GetTickCount;
if Head<>nil then
H := Head^;
if SendData<>nil then
S := SendData^;
writeln(NowToString,' ',method,' ',url,' ',S);
result.Lo := fSocket.Request(url,method,KeepAliveMS,H,S,JSON_CONTENT_TYPE,false);
result.Hi := GetCardinal(pointer(fSocket.HeaderValue('Server-InternalState')));
if Resp<>nil then
Resp^ := fSocket.Content;
if Head<>nil then
Head^ := fSocket.HeaderGetText;
writeln(result.Lo,' ',GetTickCount-tix,'ms');
end;
Leave the AllocConsole call...
So we'll know how much time is processed inside the framework, and which call is slow...
I've added a DEBUGCLI define in the official source code repository for such speed monitoring.
See http://synopse.info/fossil/fdiff?v1=071 … d7baf4656a
Offline
I have make "TEST B" with hack of SQLite3HttpClient.pas unit.
This is the client log:
2011-01-28 18:42:47 GET root SELECT Progetti.ID, Progetti.Oggetto, Progetti.Tipo
, Progetti.Fascicolo, Progetti.DataInizio, Progetti.DataFine, Progetti.Stato FR
OM Progetti ORDER BY Progetti.ID
200 281ms
2011-01-28 18:42:47 GET root SELECT Contatti.ID, Contatti.IntNome FROM Contatti
LEFT JOIN ProgettiClienti ON ProgettiClienti.IDCliente=Contatti.ID WHERE Progett
iClienti.IDProgetto="1" ORDER BY Contatti.IntNome
200 297ms
2011-01-28 18:42:48 GET root SELECT Contatti.ID, Contatti.IntNome FROM Contatti
LEFT JOIN ProgettiUtenti ON ProgettiUtenti.IDUtente=Contatti.ID WHERE ProgettiUt
enti.IDProgetto="1" ORDER BY Contatti.IntNome
200 313ms
2011-01-28 18:42:48 GET root SELECT Contatti.ID, Contatti.IntNome, ProgettiAttiv
ita.ID, ProgettiAttivita.IDProgetto, ProgettiAttivita.Oggetto, ProgettiAttivita.
Data, ProgettiAttivita.Stato FROM Contatti LEFT JOIN ProgettiAttivita ON Progett
iAttivita.IDUtente=Contatti.ID WHERE ProgettiAttivita.IDProgetto="1" ORDER BY Pr
ogettiAttivita.Data
200 297ms
2011-01-28 18:42:48 GET root SELECT Contatti.ID, Contatti.AnaCognome, Contatti.A
naNome, Contatti.Societa, Contatti.ResComune, Contatti.LegComune, Contatti.AbiM
obile, Contatti.AbiFisso, Contatti.AbiMail, Contatti.LavMobile, Contatti.LavFiss
o, Contatti.LavMail, Contatti.Ruolo FROM Contatti ORDER BY Contatti.AnaCognome
200 296ms
2011-01-28 18:42:52 GET root SELECT Contatti.ID, Contatti.IntNome, Contatti.Ruol
o FROM Contatti ORDER BY Contatti.IntNome
200 265ms
2011-01-28 18:42:52 GET root SELECT * FROM Progetti WHERE ID="1" LIMIT 1;
200 297ms
2011-01-28 18:42:53 GET root SELECT Contatti.ID, Contatti.IntNome, Contatti.Ruol
o FROM Contatti LEFT JOIN ProgettiClienti ON ProgettiClienti.IDCliente=Contatti.
ID WHERE ProgettiClienti.IDProgetto="1" ORDER BY Contatti.IntNome
200 297ms
2011-01-28 18:42:53 GET root SELECT Contatti.ID, Contatti.IntNome, Contatti.Ruol
o FROM Contatti LEFT JOIN ProgettiUtenti ON ProgettiUtenti.IDUtente=Contatti.ID
WHERE ProgettiUtenti.IDProgetto="1" ORDER BY Contatti.IntNome
200 297ms
2011-01-28 18:42:53 GET root SELECT Contatti.ID, Contatti.IntNome, ProgettiAttiv
ita.ID, ProgettiAttivita.IDProgetto, ProgettiAttivita.Oggetto, ProgettiAttivita.
Data, ProgettiAttivita.Stato FROM Contatti LEFT JOIN ProgettiAttivita ON Progett
iAttivita.IDUtente=Contatti.ID WHERE ProgettiAttivita.IDProgetto="1" ORDER BY Pr
ogettiAttivita.Data
200 312ms
2011-01-28 18:42:54 GET root SELECT ProgettiFlussi.ID, ProgettiFlussi.IDProgetto
, ProgettiFlussi.IDUtente, ProgettiFlussi.IDCliente, ProgettiFlussi.Descrizione,
ProgettiFlussi.Data, ProgettiFlussi.Importo, ProgettiFlussi.IDFattura, Progetti
Flussi.IVA FROM ProgettiFlussi WHERE ProgettiFlussi.IDProgetto="1" ORDER BY Prog
ettiFlussi.Data
200 297ms
2011-01-28 18:42:54 GET root SELECT Contatti.ID, Contatti.IntNome FROM Contatti
WHERE Contatti.ID="2"
200 297ms
2011-01-28 18:42:54 GET root SELECT Contatti.ID, Contatti.IntNome FROM Contatti
WHERE Contatti.ID="3"
200 312ms
2011-01-28 18:42:55 GET root SELECT Contatti.ID, Contatti.IntNome FROM Contatti
WHERE Contatti.ID="2"
200 297ms
2011-01-28 18:42:55 GET root SELECT Contatti.ID, Contatti.IntNome FROM Contatti
WHERE Contatti.ID="3"
200 406ms
2011-01-28 18:42:55 GET root SELECT Contatti.ID, Contatti.IntNome, ProgettiDocum
enti.ID, ProgettiDocumenti.IDProgetto, ProgettiDocumenti.Descrizione, ProgettiDo
cumenti.Data, ProgettiDocumenti.Filename, ProgettiDocumenti.Size FROM Contatti L
EFT JOIN ProgettiDocumenti ON ProgettiDocumenti.IDUtente=Contatti.ID WHERE Proge
ttiDocumenti.IDProgetto="1" ORDER BY ProgettiDocumenti.Data
200 94ms
2011-01-28 18:42:55 GET root SELECT ProgettiFatture.ID, ProgettiFatture.IDClient
e, ProgettiFatture.IDUtente, ProgettiFatture.Oggetto, ProgettiFatture.Data, Prog
ettiFatture.Importo, ProgettiFatture.Spese FROM ProgettiFatture WHERE ProgettiFa
tture.IDProgetto="1" ORDER BY ProgettiFatture.Data
200 406ms
2011-01-28 18:42:56 GET root SELECT Contatti.ID, Contatti.IntNome FROM Contatti
WHERE Contatti.ID="2" ORDER BY Contatti.IntNome
200 297ms
2011-01-28 18:42:56 GET root SELECT Contatti.ID, Contatti.IntNome FROM Contatti
LEFT JOIN ProgettiClienti ON ProgettiClienti.IDCliente=Contatti.ID WHERE Progett
iClienti.IDProgetto="1" ORDER BY Contatti.IntNome
200 297ms
2011-01-28 18:42:56 GET root SELECT ProgettiFatture.ID, ProgettiFatture.IDClient
e, ProgettiFatture.IDUtente, ProgettiFatture.Importo, ProgettiFatture.Spese, Pro
gettiFatture.IVA, ProgettiFatture.CAP, ProgettiFatture.Ritenuta, ProgettiFatture
.RitenutaUsa FROM ProgettiFatture WHERE ProgettiFatture.IDProgetto="1" ORDER BY
ProgettiFatture.Data
200 297ms
2011-01-28 18:42:57 GET root SELECT Contatti.ID, Contatti.IntNome, Contatti.Ruol
o FROM Contatti LEFT JOIN ProgettiClienti ON ProgettiClienti.IDCliente=Contatti.
ID WHERE ProgettiClienti.IDProgetto="1" ORDER BY Contatti.IntNome
200 297ms
2011-01-28 18:42:57 GET root SELECT ProgettiFlussi.Importo FROM ProgettiFlussi W
HERE ProgettiFlussi.IDProgetto="1" AND ProgettiFlussi.IDCliente="3" AND Progetti
Flussi.IDFattura > 0
200 296ms
I hope this can help you to help me
Another think about TSQLTable.GetString() I cannot find it. Do I need download last biuld of framework?
Thanks again.
Offline
OK sorry for my last stupid question I have upgrade the framework and I have found the new function.
Last edited by array81 (2011-01-28 18:24:46)
Offline
Hoho... the logs you supplied show a 290 ms response time... which is VERY slow!!!!
I'll try to reproduce the issue on some networks... and see what's happening here...
Stay tuned!
What does a "PING serverIP" looks like from your client computer?
Run it in a command line prompt (cmd.exe).
Offline
I have made the PING test, note this test is made on my Home LAN (all Windows 7 and WIFI LAN), all test of yesterday are made on Office LAN (all Windows XP and cable LAN). In any caswe I have the same problem both on Office LAN and Home LAN.
C:\>ping 192.168.1.6
Esecuzione di Ping 192.168.1.6 con 32 byte di dati:
Risposta da 192.168.1.6: byte=32 durata=1ms TTL=128
Risposta da 192.168.1.6: byte=32 durata=1ms TTL=128
Risposta da 192.168.1.6: byte=32 durata=1ms TTL=128
Risposta da 192.168.1.6: byte=32 durata=1ms TTL=128
Statistiche Ping per 192.168.1.6:
Pacchetti: Trasmessi = 4, Ricevuti = 4,
Persi = 0 (0% persi),
Tempo approssimativo percorsi andata/ritorno in millisecondi:
Minimo = 1ms, Massimo = 1ms, Medio = 1ms
C:\>
Offline
Don't worry. I hope you will reproduce the issue so you can fix it. Until next week I will work on my application to finish it.
Thanks again for your support.
Offline
Until you reproduce my problem I have another question: do my server application can know when a client application edit the database and in particular it can know how table is edit?
I like that when a client edit the db the server send a message on all the client to upgrade your data inside the grid, for this I need of a event to know when the db is edit and know how table is edit. Is this possible?
Offline
Server side synchronization
I guess you want to have some event triggered on the server side when a record is edited.
On the server side, you can use this event:
type
/// used to define how to trigger Events on record update
// - see TSQLRestServer.OnUpdateEvent property
// - returns true on success, false if an error occured (but action must continue)
TNotifySQLEvent = function(Sender: TSQLRestServer; Event: TSQLEvent;
aTable: TSQLRecordClass; aID: integer): boolean of object;
TSQLRestServer = class(TSQLRest)
(...)
/// a method can be specified here to trigger events after any table update
OnUpdateEvent: TNotifySQLEvent;
Client side synchronization
But if you want all clients to be notified, there is no direct way of broadcasting some event from the server to all clients.
It's not possible with pipe-oriented transport layer, like named pipes or the TCP/IP/HTTP protocol.
What you can do easily, and is what I used in such case, is to have a timer in your client applications which will call TSQLRestClientURI.UpdateFromServer() method to refresh the content.
With a per-second timer, it's quick and reactive.
The stateless aspect of REST allows this approach to be safe, by design.
This is handled natively by our Client User Interface classes, with the following parameter defining the User interface:
/// defines the settings for a Tab
TSQLRibbonTabParameters = object
(...)
/// by default, the screens are not refreshed automaticaly
// - but you can enable the auto-refresh feature by setting this
// property to TRUE, and creating a WM_TIMER timer to the form
AutoRefresh: boolean;
This parameter will work only if you handle the WM_TIMER message in your main application form, and call Ribbon.WMRefreshTimer.
This for example this method in the main demo (FileMain.pas unit):
procedure TMainForm.WMRefreshTimer(var Msg: TWMTimer);
begin
Ribbon.WMRefreshTimer(Msg);
end;
Offline
OK. I will try it.
Are there new about my problem with LAN? thanks
Offline
I made some modifications to the server-side of the framework.
Could you make it a try?
Could you also try with setting the following conditional (line 1587 of SynCrtSock.pas):
{$define MONOTHREAD}
// define this not to create a thread at every connection (not recommended)
I was not able to reproduce the issue as such...
Offline
I have the same result.
Is there a way to send you my application? I don't want put here (pubblic site) the link.
So you can test it and tell me if have the same problem...
If use MAIL button only you can see the message, right? Can I use it to send you the link?
thanks
Last edited by array81 (2011-02-03 08:48:24)
Offline