Hello,
I'm building an HTTP server with RTC. Each client (browser) requests a simple web page (HTML and javascript), and then afterward only makes requests for JSON data. I'm using SQLite and FireDAC database components. RAD Studio XE5 on Windows 7 Pro 64-bit. I had some problems at first with multiple clients, but I thought I had solved those by making sure that my RTC data provider handlers (C++) look as shown below. I've read all of the FireDAC and RTC articles on multi-threading, and I think I'm doing things correctly now. My RtcHttpServer has MultiThreaded = true.
My problem is that if I open a relatively small number of clients (10), and increase their polling rate to about 10 times/sec, I pretty quickly get an access violation that is reported to be in the VCL CompareText() function. I checked the source for rtcSrvModule.pas, and it does make one call to CompareText() in TRtcBaseServerModule.DoExecute(). I did some googling, and I found an article on EDN about an issue regarding this function and non-thread-safe VCL (link below). The problem they discuss seems to be related to creating/destroying TDataModule. I am not doing that. I create/destroy FireDAC and RTC objects, as shown in my handler code. My server is built as described in the tutorials, with a TRtcServerDataLink and TRtcDataProvider components in a TDataModule, and a TRtcHttpServer on a separate TForm. Am I doing something wrong in my design or code that causes this problem? Is the problem really occurring in CompareText(), and is the issue described on EDN a problem for RTC?
Thanks for any advice you can provide.
Joe
https://forums.codegear.com/message.jspa?messageID=595331void __fastcall THttpDataModule::RTEVENTDataProviderDataReceived(TRtcConnection *Sender)
{
TRtcDataServer *DS = (TRtcDataServer*)Sender;
if (DS->Request->Complete) {
// create a new TFDConnection with settings identical to Connection
TFDConnection *TempConnection = new TFDConnection( this );
TempConnection->ConnectionString = Connection->ConnectionString;
TempConnection->UpdateOptions->LockWait = true;
// create a new TFDQuery, apply settings, assign SQL, execute, FetchAll()
TFDQuery *FDQuery = new TFDQuery( this );
FDQuery->Connection = TempConnection;
FDQuery->ResourceOptions->CmdExecMode = amNonBlocking;
FDQuery->SQL->Assign( RTEventQuerySQL );
FDQuery->Active = true;
FDQuery->FetchAll();
// use TRtcArray to get "flat" JSON compatible with D3
TRtcArray *RtcArray = new TRtcArray;
DelphiDataSetToRtcArray( FDQuery, RtcArray );
DS->Write( RtcArray->toJSON() );
delete( RtcArray );
// destroy temporary TFDQuery and TFDConnection
FDQuery->Active = false;
FDQuery->SQL->Clear();
delete( FDQuery );
TempConnection->Connected = false;
delete( TempConnection );
}
}