fabiotj Posted March 10 Posted March 10 I need to start a TUniTimer in the ServerModule that will check the active sessions of the application and perform some processes in the database. But when I try to do as below I get an Access Violation error: procedure TServerModule.CleanupTimerEvent(Sender: TObject); var myQuery : TFDQuery; begin myQuery := TFDQuery.Create(Self); myQuery.Connection := MainModule.SQLConnection; (here the Access Violation error occurs). end; This is just a simple example. In my real case I call a procedure and inside it I access the MainModule.SQLConnection. What is the correct way to access it? After doing a lot of research here on the Forum, I have tried several approaches but without success. Quote
Abaksoft Posted March 12 Posted March 12 On 3/10/2025 at 8:13 PM, fabiotj said: I need to start a TUniTimer in the ServerModule ... Goodmorning Fabio, You have two problems here : 1. First is about Sessions : - ServerModule has the control of all sessions - You can not control one session with ServerModule - So, the simple fact of writing things on ServerModule, that affect one session will cause an AV (acces violation) Like : UniMainModule... UniMainForm... To better understand : You can not do this : procedure TUniServerModule.UniGUIServerModuleCreate(Sender: TObject); begin MainModule.UniMainModule.v1:=11; // Or UniMainForm... end; (v1 is declared on UniMainModule) For doing this, we are asking to the server to Set a variable v1 on a session (but wich session ???) that is why the AV appears. 2. Second is about Timer : - UniTimer is dedicated for Sessions (MainForm, UniMainModule, ...) - UniThreadTimer is dedicated for ServerModule. You have to lock and release it before using your procedures inside : procedure TUniServerModule.UniThreadTimer1Timer(Sender: TObject); begin UniThreadTimer1.Lock; try //============== Procedure_DoingSomeThings; //============== finally UniThreadTimer1.Release; end; end; 1 Quote
fabiotj Posted March 12 Author Posted March 12 Thank you very much for the explanation. ThreadTimer = OK. But, 1) Can I have an exclusive FDConnection (although I know it is not indicated) in the ServerModule to perform a simple Query operation? 2) Or is there still a way to specify which section I want to use so that through it I can access the FDConnection of the MainModule? Something like: myQuery.Connection := EspecSession(SessionID).MainModule.SQLConneciton; Quote
fabiotj Posted March 12 Author Posted March 12 I managed to do it with a direct connection to the ServerModule. Thanks Eduardo. If someone later reads this post and knows how to access a specific MainModule of a session or even how to access anything in a specific session, I would appreciate it because it could be useful in the future. Quote
Abaksoft Posted March 12 Posted March 12 2 hours ago, fabiotj said: it could be useful in the future. Sure, ... i think Websokets is a keyword. I didn't play with it, but i already hear a such approach. 1 Quote
fabiotj Posted March 12 Author Posted March 12 Yes, I tried websocket before using the current method, but when I went to implement the dedicated websocekt server to run in conjunction with HyperServer I encountered many local problems to run as a Windows service etc... so due to urgency I gave up, but WebSocket really is very good, my project worked with it but not on HyperServer because it is Multi-Instance. Quote
Abaksoft Posted March 12 Posted March 12 7 hours ago, fabiotj said: Something like: myQuery.Connection := EspecSession(SessionID).MainModule.SQLConneciton; The Classical method in Unigui for connection to a DB, is to connect on UniMainModule.OnCreate Event for each new session (using pooling). Why are you trying to connect a second time from UniSeverModule and pointing to this UniMainModule connection ? What is the pupose ? Quote
Norm Posted March 12 Posted March 12 (edited) 8 hours ago, fabiotj said: I managed to do it with a direct connection to the ServerModule. Thanks Eduardo. Instead of putting the sqlConnection in the ServerModule I do it in a separate DataModule that I reference from the ServerModule. That way I avoid cluttering the ServerModule with database handling functions. I also use this to handle incoming API requests. e.g. unit ServerModule; interface uses Classes, SysUtils, uniGUIServer, uniGUIMainModule, uniGUIApplication, uIdCustomHTTPServer, uniGUITypes, MainModule, uniThreadTimer, uniGuiServerUtils, SyncObjs; type TUniServerModule = class(TUniGUIServerModule) .... ..... end; function UniServerModule: TUniServerModule; implementation {$R *.dfm} uses UniGUIVars, uIdGlobal, //My data module dData; ... ... procedure TUniServerModule.TimerTimer(Sender: TObject); begin Timer.Lock; try //*** Call datamodule methods dmDB.CheckConnections; finally Timer.Release; end; end; function TUniServerModule.HandleHTTPPostRequest(var wPostBody: String; wIPAddress : String; var wRespText: String) : Integer; begin Timer.Emanled := false; try //*** Call datamodule methods Result := dmDB.HandlePostRequest(wPostBody, wIPAddress, wRespText); finally Timer.Enabled := True; end; end; procedure TUniServerModule.UniGUIServerModuleHTTPCommand( ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo; var Handled: Boolean); var aParams : String; aStream : TStream; aPostBody : string; aHTML : String; aData : TStringList; aRespNo : Integer; aRespText : String; aIPAddress : String; begin if (ARequestInfo.Command = 'GET') and (ARequestInfo.URI = '/') then begin .... .... end else if ARequestInfo.Command = 'POST' then begin aParams := UpperCase(ARequestInfo.URI); aStream := ARequestInfo.PostStream; if assigned(aStream) then begin aStream.Position := 0; aPostBody := ReadStringFromStream(aStream); aRespNo := HandleHTTPPostRequest(aPostBody, aIPAddress, aRespText); AResponseInfo.ResponseNo := aRespNo; AResponseInfo.FreeContentStream := True; AResponseInfo.ContentStream := TStringStream.Create(aPostBody); AResponseInfo.ContentLength := AResponseInfo.ContentStream.Size; AResponseInfo.ContentType := 'application/json'; Handled := True; end end end; Edited March 12 by Norm Typo 1 1 Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.