Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// simple SOA server using a callback for long process ending notification
- program Project31LongWorkServer;
- uses
- {$I SynDprUses.inc} // use FastMM4 on older versions of Delphi
- SysUtils,
- Classes,
- SynCommons,
- SynLog,
- mORMot,
- SynBidirSock,
- mORMotHttpServer,
- Project31LongWorkCallbackInterface in 'Project31LongWorkCallbackInterface.pas';
- {$APPTYPE CONSOLE}
- type
- TLongWorkServiceThread = class(TThread)
- protected
- fCallback: ILongWorkCallback;
- fWorkName: string;
- procedure Execute; override;
- public
- constructor Create();
- procedure SetCallback(const workName: string; const callback: ILongWorkCallback);
- end;
- TLongWorkService = class(TInterfacedObject,ILongWorkService)
- protected
- fTotalWorkCount: Integer;
- fThread : TLongWorkServiceThread;
- procedure OnClientDisconnected(sender : TObject);
- public
- constructor Create();
- procedure StartWork(const workName: string; const onFinish: ILongWorkCallback);
- function TotalWorkCount: Integer;
- end;
- constructor TLongWorkService.Create();
- begin
- inherited Create;
- fThread := TLongWorkServiceThread.Create();
- end;
- procedure TLongWorkService.OnClientDisconnected(sender : TObject);
- begin
- fThread.SetCallback('', nil);
- end;
- procedure TLongWorkService.StartWork(const workName: string;
- const onFinish: ILongWorkCallback);
- begin
- InterlockedIncrement(fTotalWorkCount);
- fThread.SetCallback(workName, onFinish);
- end;
- function TLongWorkService.TotalWorkCount: Integer;
- begin
- result := fTotalWorkCount;
- end;
- constructor TLongWorkServiceThread.Create();
- begin
- inherited Create(false);
- fCallback := nil;
- fWorkName := '';
- FreeOnTerminate := true;
- end;
- procedure TLongWorkServiceThread.Execute;
- var tix: Int64;
- begin
- TSQLLog.Add.Log(sllInfo,'%.Execute(%) started',[self,fWorkName]);
- tix := GetTickCount64;
- repeat
- Sleep(1000); // some hard work
- if Assigned(fCallback) then
- begin
- try
- if Random(100)>20 then
- fCallback.WorkFinished(fWorkName,GetTickCount64-tix) else
- fCallback.WorkFailed(fWorkName,'expected random failure');
- except
- //connection error
- end;
- end;
- TSQLLog.Add.Log(sllInfo,'%.Execute(%) notified',[self,fWorkName]);
- until Terminated;
- end;
- procedure TLongWorkServiceThread.SetCallback(const workName: string; const callback: ILongWorkCallback);
- begin
- fCallback := callback;
- fWorkName := workName;
- end;
- procedure Run;
- var HttpServer: TSQLHttpServer;
- Server: TSQLRestServerFullMemory;
- WSServer: TWebSocketServerRest;
- LongWorkService : TLongWorkService;
- begin
- Server := TSQLRestServerFullMemory.CreateWithOwnModel([]);
- try
- Server.CreateMissingTables;
- LongWorkService := TLongWorkService.Create;
- Server.ServiceDefine(LongWorkService,[ILongWorkService]{,sicShared}).
- ByPassAuthentication := true;
- HttpServer := TSQLHttpServer.Create('8888',[Server],'+',useBidirSocket);
- try
- WSServer := HttpServer.WebSocketsEnable(Server,PROJECT31_TRANSMISSION_KEY);
- WSServer.Settings.SetFullLog; // full verbose logs for this demo
- WSServer.Settings.OnClientDisconnected := LongWorkService.OnClientDisconnected;
- // WSServer.Settings.OnClientConnected := OnClientConnected;
- WSServer.Settings.HeartbeatDelay := 5000;
- TextColor(ccLightGreen);
- writeln('WebSockets Long Work Server running on localhost:8888'#13#10);
- TextColor(ccWhite);
- writeln('Please compile and run Project31LongWorkClient.exe'#13#10);
- TextColor(ccLightGray);
- writeln('Press [Enter] to quit'#13#10);
- TextColor(ccCyan);
- readln;
- finally
- HttpServer.Free;
- end;
- finally
- Server.Free;
- end;
- end;
- begin
- with TSQLLog.Family do begin // enable logging to file and to console
- Level := LOG_VERBOSE;
- EchoToConsole := LOG_VERBOSE;
- PerThreadLog := ptIdentifiedInOnFile;
- end;
- WebSocketLog := TSQLLog; // verbose log of all WebSockets activity
- try
- Run;
- except
- on E: Exception do
- ConsoleShowFatalException(E);
- end;
- end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement