#1 mORMot Framework » LongWorkClient Demo for Web » 2022-12-02 11:36:55

radexpol
Replies: 1

Can someone help me how to implement \Samples\31 - WebSockets to work on web together with delphi client? 

I tried postman:
ws://localhost:8888/root/LongWorkCallback.WorkFinished

Request URL: http://localhost:8888/root/LongWorkCallback.WorkFinished
Request Method: GET
Status Code: 400 WebSocket Upgrade Error

I have no idea how to start the websocket listener that will handle particular events.

#2 mORMot Framework » Websocket - message order » 2022-11-24 10:16:11

radexpol
Replies: 0

I have a web application that allows to login and starts listening to events from the server. How to deal with message order when the WebSocket sometimes loose connection to server? Does the server should queue the message to particular listener and send all data after reconnection?

#4 Re: mORMot Framework » [SOA] Use methods as API user and logged user. » 2022-10-18 19:48:48

How to access "TSQLRestServerURIContext.JWTContent" from GetVehicles method to vary response depend on data stored in JWT i.e. "userLevel"?

#5 Re: mORMot Framework » AuthenticationNone » 2022-10-05 09:31:56

I've added:

function TMyAuthenticator.Auth(Ctxt: TSQLRestServerURIContext): boolean;
begin
  Result := True;
  var body: TDocVariantData;
  body.InitFast(10,dvObject);
  Ctxt.ReturnsJson(variant(body));
end;

I'm not sure if self-made response like that is a good practice.

#6 Re: mORMot Framework » AuthenticationNone » 2022-10-04 20:24:23

It does not help:

  TMyAuthenticator = class(TRestServerAuthenticationUri)
  protected
    function Auth(Ctxt: TRestServerUriContext): boolean; override;
  end;

function TMyAuthenticator.Auth(Ctxt: TSQLRestServerURIContext): boolean;
begin
  Result := Ctxt.InputUtf8['UserName']<>'xyz'  // -> TRUE under debug
end;

what I am doing wrong?

#7 mORMot Framework » AuthenticationNone » 2022-10-04 19:14:54

radexpol
Replies: 3

I'm trying to implement simple authentication based on username and password:

  TMyAuthenticator = class(TRestServerAuthenticationNone)
  protected
    function Auth(Ctxt: TRestServerUriContext): boolean; override;
  end;

  Server.AuthenticationRegister(TMyAuthenticator);


function TMyAuthenticator.Auth(Ctxt: TSQLRestServerURIContext): boolean;
begin
  Result := True;
end;

but the url http://localhost/auth?UserName=xxx&Password=yyy displays an error:

{
"errorCode":400,
"errorText":"Bad Request"
}

How to get the UserName and Password from Ctxt?

#8 mORMot Framework » Forum Search future does not work » 2022-09-21 17:10:55

radexpol
Replies: 3

I noticed that the search does not work, for example I've typed IgnoreCertificateErrors and checked mORMot Framework, nothing found. That's not true, I see a lot of threads with text "IgnoreCertificateErrors", this is frustrating when I have to wait 30 second to retry all other variations of my search criteria.

#9 mORMot Framework » Safe HttpServer constructor » 2022-09-06 13:18:15

radexpol
Replies: 1
TMyClass = class
  httpServer: TSQLHttpServer;
  list: TStringList;
  constructor Create;
end;
 
constructor TMyClass .Create;
begin
    list := TStringList.Create;
    HttpServer := TSQLHttpServer.Create('2080',[Server]);  -> exception port 2080 already in use
end;

I think that the constructor of TSQLHttpServer should be safe for object instancing, and does not start listening. Instead the "StartListening" method (like Indy TCPServer) could start the thread (bind and open listening port).

#10 Re: mORMot Framework » Access violation DynArrayLoadJSON » 2022-09-04 22:10:17

Thank you, the:
ShowMessage(Utf8ToString(DynArraySaveJson(ar, TypeInfo(TArray<TRec>))));
also is OK.

#11 Re: mORMot Framework » Access violation DynArrayLoadJSON » 2022-09-04 19:41:02

  var 
     x: UTF8String;  
     r: TRec;
     ar: TArray<TRec>;
  begin
    r.firstname := 'ssss';
    ar := ar + [r];
    x := '[]';

    DynArrayLoadJSON(ar, UniqueRawUTF8(x),  TypeInfo(TArray<TRec>));

    ShowMessage(x);

it does not raise AV but the x does not contain any data, just empty array as initialized

#12 Re: mORMot Framework » Access violation DynArrayLoadJSON » 2022-09-04 10:10:09

I'm using 10.4.

I want to convert json into array of TRec structure, something like TJson.JsonToObject<TPerson>(Memo1.Lines.Text);

#13 mORMot Framework » Access violation DynArrayLoadJSON » 2022-09-04 08:44:08

radexpol
Replies: 6
type
  TRec = packed record
    firstname: string;
  end;

procedure Test;
var
  r: TRec;
  ar: TArray<TRec>;
  x: RawUtf8;
begin
  r.firstname := 'sdf';
  ar := ar + [r];
  DynArrayLoadJSON(ar, UniqueRawUTF8(x),  TypeInfo(TArray<TRec>));  -> access violation

An error occured in line:
Ctxt.Json := GotoNextNotSpace(Ctxt.Json);  -> Ctxt.Json is nil
in method:
_JL_DynArray

#14 Re: mORMot Framework » TryLoadLibray PostgreSql lib » 2022-08-30 19:26:46

I used Microsoft Sysinternals Procmon.exe to find what files my project is looking for and what files are missing, that helped me to find all dll files required by PostgreSQL (7 dlls AFAIR)

#15 Re: mORMot Framework » TSQLDBServerHttpApi with tmThreadPool » 2022-07-20 08:35:45

  
FHttpServer.FServer.OnHttpThreadTerminate = function() begin Properties.EndCurrentThread; end;

Damn! After reading your post I was hoping that the newest delphi allows to implement anonymous event handlers, so I immediately tried it in my Alexandria smile Seems that we still have to wait for that extra feature.

#16 Re: mORMot Framework » Problem with ReduceAsArray() » 2022-05-11 09:38:20

Instead of 

for var idx: Integer := 0 to 100 do

you can use

for var idx := 0 to 100 do

#17 Re: mORMot Framework » TAesWriteStream replacement » 2022-05-04 17:01:57

I'm also interested in encrypted logs to prevent my competitors from understanding internal flow in application.

#18 mORMot Framework » Unregister Service » 2022-02-12 10:11:01

radexpol
Replies: 1

How to unregister service from TRestClientUri that has been registered by ServiceDefine( )? I would like to remove all registered services on reconnect without destroying TRestClientUri. I cannot find the ServiceUndefine or ServiceContainer.Clear;

#19 Re: mORMot Framework » Interface Based Services - send TStrings » 2022-01-30 17:35:13

How to store key+value in:

/// a dynamic array of UTF-8 encoded strings
  TRawUtf8DynArray = array of RawUtf8;

?

#20 Re: mORMot Framework » Interface Based Services - send TStrings » 2022-01-30 13:01:17

Let me try to answer myself.

TVehicle = record
  Make: string;
  Model: string;
  TechnicalDetails: IKeyValue<string, string>;
end;

TTest = class(TInterfacedObject, ITest)
   procedure GetVehicle(out vehicle: TVehicle);
end;

procedure TTest.GetVehicle(out vehicle: TVehicle);
begin
   vehicle.Make := 'volvo';
   vehicle.TechnicalDetails := Collections.NewKeyValue<string, string>;
   vehicle.TechnicalDetails.TryAdd('Engine', 'Diesel');
end;

can I use safely the code like above ?

#21 Re: mORMot Framework » Interface Based Services - send TStrings » 2022-01-30 11:29:07

OK, how to deal with stringlist as a part of record?

TVehicle = record
  Make: string;
  Model: string;
  TechnicalDetails: TStrings;
end;

TTest = class(TInterfacedObject, ITest)
   procedure GetVehicle(out vehicle: TVehicle);
end;

procedure TTest.GetVehicle(out vehicle: TVehicle);
begin
   vehicle.Make := 'volvo';
   vehicle.TechnicalDetails := TStringList.Create -> ????
   vehicle.TechnicalDetails['Engine'] := 'Diesel';
end;

The framework probably won't create/free that stringlist for me?

#22 mORMot Framework » Interface Based Services - send TStrings » 2022-01-30 00:19:55

radexpol
Replies: 9

Regarding the documentation I'm trying to send the TStringList (dictionary).

TTest = class(TInterfacedObject, ITest)
   procedure GetParams(out params: TStrings);
end;

procedure TTest.GetParams(out params: TStrings);
begin
  params := TStringlist.create;
  params.Values['name'] := 'John';
end;

how to free the params stringlist (do I have to free that list?)

#23 Re: mORMot Framework » Immediate WebSocketsClosed event » 2021-12-01 10:53:13

@AB fantastic, zero extra code for reconnecting feature! Thank you. When do you plan to implement reconnection?

#24 Re: mORMot Framework » Immediate WebSocketsClosed event » 2021-12-01 08:38:40

So what is preferred method for websocket reconnection?

procedure WebSocketsClosed(  );
begin
  timerReconnect.Enabled := True;
end;

procedure WebSocketUpgraded(  );
begin
  serviceIntf.RegisterListener('xxxx', ServiceNotification);
end;  

procedure Reconnect;
begin
  if assigned(connector) then
   connector.Free;  
  ServiceNotification := nil;
  serviceIntf := nil;

  connector := TRestHttpClientWebsockets.Create('127.0.0.1', '1414', TOrmModel.Create([]), False, '', '', 0, 0, 3000);
  ServiceNotification := TServiceNotification.Create(connector, IServiceNotification);
  with connector do
  begin
    Settings.ClientAutoUpgrade := True;
    OnWebSocketsUpgraded := WebSocketsUpgraded;
    OnWebSocketsClosed := WebSocketsClosed;
    ServiceDefine([IService], sicShared);
    connector.Services.Resolve(IService, serviceIntf);
  end;
  connector.WebSocketsUpgrade('aaa');
  timerReconnect.Enabled := false;
end;

procedure timerReconnect(Sender: TObject);
begin
  try
    Reconnect;
  except
  end; 
end;

is this correct way ?

#25 Re: mORMot Framework » Immediate WebSocketsClosed event » 2021-11-29 12:26:27

I thought that websocket will raise on OnWebSocketsClosed event after 5 retries (DisconnectAfterInvalidHeartbeatCount) x HeartbeatDelay (3000) = 5 times x 3 seconds = 15 seconds.

#26 mORMot Framework » Immediate WebSocketsClosed event » 2021-11-28 23:59:04

radexpol
Replies: 6

How to set the websockets retry settings to prevent from raising the OnWebSocketsClosed event immediately after I kill the server.

That'my my code:

  with connector do
  begin
    KeepAliveMS := 1000 * 60 * 5; //5 mins
    Compression := [hcDeflate];
    Settings.HeartbeatDelay := 3000;
    Settings.DisconnectAfterInvalidHeartbeatCount := 5;
    Settings.ClientAutoUpgrade := True;
    OnWebSocketsUpgraded := WebSocketsUpgraded;
    OnWebSocketsClosed := WebSocketsClosed;
    ServiceDefine([IService], sicShared);
    if not connector.Services.Resolve(IService, serviceIntf) then
      raise EServiceException.Create('Service unavailable');
  end;

and seems that mORMot does not respects those settings.

#27 mORMot Framework » [SOA] Use methods as API user and logged user. » 2021-11-19 19:49:37

radexpol
Replies: 4

I would like to use one endpoint for logged users as well as API users (one time token). Let's say I have an endpoint:

type
  TVehicles = class(TInterfacedObject,IVehicles) 
     procedure GetVehicles(const outputVehicles: TArray<TVehiclesStruct>);
  end;

implementation

//pseudocode

procedure TVehicles.GetVehicles(const outputVehicles: TArray<TVehiclesStruct>);
begin
   //logged user ?
   if (var user := loggedUsers.findtoken(request.header.token)) then
      outputVehicles.add('select name, owner from vehicles where owner = user')
  else
  //maybe one-time request based on token key ?
  if (var token:= apiTokens.findtoken(request.header.token)) then
    outputVehicles.add('select name, owner from vehicles  '+
                             'join tokens where owner = token.owner '+
                             'and token =  context.token ');

  else raise Exception.Create('not authorized');
end;

implementation

ServiceDefine(TVehicles ,[IVehicles],sic????);

What are the best practices for such issue, creating the copy of each API endpoints does not seems to be nice solution.

//*********************************
type
    TVehiclesForUsers = class(TInterfacedObject,IVehiclesForUsers) 

implementation

ServiceDefine(TVehiclesForUsers, [IVehiclesForUsers], sicPerUser);
end;

//*********************************

type
     TVehiclesForTokenRequests = class(TInterfacedObject,IVehiclesForTokenRequests) 

implementation

ServiceDefine(TVehiclesForTokenRequests,[IVehiclesForTokenRequests], sicShared);
end;

//*********************************

I have a hundreds of methods, about 80% of them must be both - user accessible and token accessible and the output data depends on user or token privileges.

#28 mORMot Framework » SOA - Pass unknown record » 2021-11-09 23:51:30

radexpol
Replies: 1

I would like to pass different record types as a result of procedure. Is that possible, or any suggestion how to deal with it?

type
  TVehicleType = (vtBus, vtCar);

type
  TCommonAttributes = packed record
    wheelCount: integer;
  end;

  TCar = packed record
     common: TCommonAttributes;
     power: integer;
  end; 

  TBus =  packed record
    common: TCommonAttributes;
    seats: integer;
  end;

type
  TVehicles = class(TInterfacedObject,IVehicles) 
     procedure GetVehicle(const VehicleType: TVehicleType; out outputVehicle: pointer);  --> pointer is not accepted by mORMot
  end;
implementation

procedure TVehicles.GetVehicle(const VehicleType: TVehicleType; out outputVehicle: pointer); 
begin
   case VehicleType of
     vtBus: begin
                  var busInfo: TBus;
                  busInfo.common.wheelCount := 6;
                  busInfo.seats := 40;
                  outputVehicle := @busInfo;
               end;
end;

I hope I won't have to create the separate methods for all vehicle kinds such as:

procedure GetBus(out outputVehicle: TBus);

 

Any smart solution for such issue?

#29 Re: mORMot Framework » Access Violation when using mORMot 2 / DLL / Runtime packages » 2021-09-30 07:28:43

@sakura, I have no more code, nothing to disable. That problem appears when using runtime packages.

#30 mORMot Framework » Access Violation when using mORMot 2 / DLL / Runtime packages » 2021-09-29 21:21:24

radexpol
Replies: 3

Delphi 10.4

An application raises an exception on close.

---------------------------
Debugger Exception Notification
---------------------------
Project Project3.exe raised exception class EAccessViolation with message 'Access violation at address 5005FC74 in module 'rtl270.bpl'. Read of address 03592104'.
---------------------------
Break   Continue   Help   
---------------------------

Library:

library Project4;

uses
  mormot.core.variants;

{$R *.res}

begin
end.

Application

uses 
  mormot.core.variants;

procedure TForm.OnButtonClick(Sender: TObject);
begin
  var h := LoadLibrary('Project4.dll');
  FreeLibrary(h);
end;

Both application and dll compiled with checked Link with runtime packages with one package vcl


When I commented:

initialization
 // InitializeUnit;

in mormot.core.variants application closes without any errors.

#31 Re: mORMot Framework » A lot of hints while using mORMot 2 » 2021-09-27 14:37:25

I'm using 10.4, updated mORMot now ("enhanced and optimized RTTI values comparison")

@sakura, Clean before Build to see those errors.

#32 mORMot Framework » A lot of hints while using mORMot 2 » 2021-09-26 18:03:07

radexpol
Replies: 9
[dcc32 Hint] mormot.core.unicode.pas(2437): H2443 Inline function 'Unicode_AnsiToWide' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.unicode.pas(6815): H2443 Inline function 'Unicode_CodePage' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.buffers.pas(8800): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.buffers.pas(8809): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.data.pas(3166): H2443 Inline function 'NewSynLocker' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.data.pas(3214): H2443 Inline function 'NewSynLocker' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.data.pas(9583): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.data.pas(9651): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.json.pas(5425): H2443 Inline function 'Unicode_CodePage' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.log.pas(2905): H2443 Inline function 'GetModuleHandle' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.log.pas(5245): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.threads.pas(1044): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.threads.pas(1268): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.threads.pas(1669): H2443 Inline function 'NewSynLocker' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.threads.pas(1794): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.threads.pas(1954): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.threads.pas(2015): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.threads.pas(2023): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.threads.pas(2115): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.threads.pas(2199): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.core.threads.pas(2201): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.crypt.secure.pas(2170): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.rest.core.pas(2947): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.orm.client.pas(648): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.rest.client.pas(1772): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.rest.client.pas(2092): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.rest.client.pas(2281): H2443 Inline function 'PostMessage' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.rest.client.pas(2869): H2443 Inline function 'LibraryOpen' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.rest.client.pas(2879): H2443 Inline function 'LibraryClose' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.rest.client.pas(2899): H2443 Inline function 'LibraryClose' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.soa.client.pas(444): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.soa.client.pas(912): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.orm.server.pas(1388): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.soa.server.pas(2123): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list
[dcc32 Hint] mormot.rest.server.pas(6254): H2443 Inline function 'SleepHiRes' has not been expanded because unit 'Winapi.Windows' is not specified in USES list

Those hints are the only one I'm getting while compiling huge project. I'm trying to have clean code out of any hints. I can fix that hints myself by adding required uses, but next mORMot update will override my changes.

#33 Re: mORMot Framework » mORMot 2 does not compile » 2021-09-23 08:49:19

OK, I decided to store all required files in my components repository, except of \src which I've linked to your mORMot repository : https://github.com/synopse/mORMot2/trunk/src, so this folder will be always up to date.

#34 Re: mORMot Framework » mORMot 2 does not compile » 2021-09-22 14:40:56

OK, I've downloaded those files from https://synopse.info/files/mormot2static.7z, that's pity that the files are not included in repository, I've configured my SVN to link mormot folder to https://github.com/synopse/mORMot2/trunk, to automatically synchronize my components\mORMot folder, but this is completely unuseful, if the repository does not contain all required to compile files.

#35 mORMot Framework » mORMot 2 does not compile » 2021-09-22 14:03:38

radexpol
Replies: 5

In the: mormot.lib.z compilation error

[dcc32 Error] mormot.lib.z.pas(601): E1026 File not found: '..\..\static\delphi\zlibdeflate.obj'
[dcc32 Error] mormot.lib.z.pas(602): E1026 File not found: '..\..\static\delphi\zlibtrees.obj'
[dcc32 Error] mormot.lib.z.pas(603): E1026 File not found: '..\..\static\delphi\zlibinflate.obj'
[dcc32 Error] mormot.lib.z.pas(604): E1026 File not found: '..\..\static\delphi\zlibinftrees.obj'

Delphi 10.4, 32bit

#36 mORMot Framework » Json Escape characters \u » 2021-08-05 09:06:58

radexpol
Replies: 1

How to get the Json Text with escaped diacritics?

  var j := _ObjFast([]);
  j.name := 'Россия';
  ShowMessage( VariantToString(j)); //displays {"name":"Россия"} instead of {"name":"\u0420\u043E\u0441\u0441\u0438\u044F}

#37 Re: mORMot Framework » HTML character entities decode » 2021-05-01 17:33:24

Does not work for hex encoded characters for example &#x22;

#38 mORMot Framework » HTML character entities decode » 2021-05-01 16:31:23

radexpol
Replies: 3

Can I find a method that converts the html character entities to normal text?

Something like: result := HtmlEncode('&#x22;Me&You&#x22;&amp;');  -> "Me&You"&

#39 Re: mORMot Framework » Keep Alive » 2021-04-21 21:44:42

How can I change ping time?

#40 mORMot Framework » Keep Alive » 2021-04-21 20:04:58

radexpol
Replies: 3

Does the TSQLHttpClientWebsockets supports keep alive? I mean I want to know if my RestHttpServer is alive. Now I've implemented the extra thread for that but maybe I can use any built-in mechanism. I'm also not sure if I can use the TSQLHttpClientWebsockets requests from thread.

type
  TPingThread = class(TThread)
  private
    Connector: TSQLHttpClientWebsockets;
    event: TEvent;
    procedure Ping;
  protected
    procedure Execute; override;
  public
    procedure Terminate;
    constructor Create(AConnector: TSQLHttpClientWebsockets);
    destructor Destroy; override;
  end;

implementation

procedure TPingThread.Execute;
begin
  inherited;
  while not Terminated do
  begin
    if event.WaitFor(10000) = wrTimeout then
      Ping
  end;
end;

procedure TPingThread.Ping;
begin
  if not Connector.ServerTimestampSynchronize then  -> is Connector thread safe ?
    PostMessage(Application.Handle, WM_QUIT, 0, 0);// Terminate;
end;

#41 Re: mORMot Framework » Service without GUI » 2021-04-17 19:24:30

Sorry, my mistake. I would like to create invisible client instance (>100 instances).

So, does the deamon helps me or use the while true Application.ProcessMessages;

program FishShopDaemon;

uses
   ....  
   mORMot;

begin
  connector := TSQLHttpClientWebsockets.Create('127.0.0.1', '1414', TSQLModel.Create([]), False, '', '', 30000, 30000, 30000);
  connector.WebSocketsUpgrade(myPassword);
  if not connector.ServerTimeStampSynchronize then
    raise EServiceException.Create('Error connecting to the server');
  connector.ServiceDefine([IService],sicShared);

  if not connector.Services.Resolve(IService,Service) then
    raise EServiceException.Create('Service unavailable');

   ???????  -> repeat until application.processMessages?

  connector.Free;

end.

#42 mORMot Framework » Service without GUI » 2021-04-17 09:38:54

radexpol
Replies: 5

How to implement the SOA Service without GUI/Console/Service?

program FishShopDaemon;

uses
   ....  
   mORMot;

begin
  fServer := TSQLRestServerFullMemory.CreateWithOwnModel([], False, FISHSHOP_ROOT);
  fServer.ServiceDefine(instance, [IFishShop], FISHSHOP_CONTRACT);
  fHttpServer := TSQLHttpServer.Create(FISHSHOP_PORT, fServer);

            ???????  -> repeat until application.processMessages?

  fServer.Free;
  fHttpServer.Free;

end.

#43 Re: mORMot Framework » mORMot2 examples and documenation. Where should a beginner start? » 2021-01-27 11:17:40

AB, please, pleeeease add a lot of sample code to the methods you describing, as you wrote in one of your old posts "the sample is better than million of words", if I see the sample usage it helps me use it in my code.

#44 Re: mORMot Framework » Events without subscribe » 2020-12-30 19:45:20

So, you meant:

type
  ICallbacks = interface
    procedure Event1(const parameter: string);
    procedure Event2(const parameter: string; const Param2: array);
     ....
    procedure Event100(const parameter: string; const Param222: array);
  end

IEvents = interface()
public
  procedure Subscribe(const callback: ICallbacks);

#45 mORMot Framework » Events without subscribe » 2020-12-30 14:40:37

radexpol
Replies: 3

[Websockets] I would like to send all authenticated users a lot of different events. Can I do it without defining callback interface in any dedicated method parameter?

Based on Project31ChatServer.dpr, can I send the NotifyBlaBla without subscribing to any event by Join( ) method.

If it is not possible what is the right solution for subscribing to "all" events? Below is one of my ideas

type
  IEvent1 = interface
    procedure Event1(const parameter: string)
  end

  IEvent2 = interface
    procedure Event2(const parameter: string; const Param2: array)
  end

IEvents = interface()
public
  procedure Subscribe(const callback: IEvent1);
  procedure Subscribe(const callback: IEvent2);
  ...
  procedure Subscribe(const callback: IEvent100);

#46 Re: mORMot Framework » SOA - reconnect » 2020-12-20 21:15:26

I thought so.

I've implemented it like that:

fClient.OnFailed := Err;

procedure tRestClient.Err(Sender: TSQLRestClientURI; E: Exception;
  Call: PSQLRestURIParams);
begin
  if not StatusCodeIsSuccess(Call.OutStatus) then
    postmessage(Form1.Handle, WM_FAIL, 0, 0);
end;

procedure TForm1.RestartClient(var message: TMessage); message WM_FAIL;
begin
   StartStopClient(Restart);
end;

that's correct procedure?

#47 Re: mORMot Framework » SOA - reconnect » 2020-12-19 16:29:17

Using the Demos\ThirdParty\Goerge demo.

1. I'm starting the server Websocket/Json
2. Starting client
3. Clicked the SUM method - response is ok
4. Closed the server
5. Started server
6. Clicked the SUM method - an error occured:


---------------------------
Debugger Exception Notification
---------------------------
Project mORMotRESTcl.exe raised exception class EInterfaceFactoryException with message 'TInterfacedObjectFakeClient.FakeCall(IRestMethods.Sum) failed: 'URI service/RestMethods.Sum [80.6,12.3] returned status 'Not Found' (404 - Network problem or request timeout)''.
---------------------------
Break   Continue   Help   
---------------------------

So I thought that I have to close the REST client connection after I get that error. What's the other solution? Free the client and recreate an object again?

#48 mORMot Framework » SOA - reconnect » 2020-12-19 00:09:07

radexpol
Replies: 6

I'm checking for connection to rest server using ServerTimestampSynchronize as documented:

    /// you can call this method to call the remote URI root/Timestamp
    // - this can be an handy way of testing the connection, since this method
    // is always available, even without authentication
    // - returns TRUE if the client time correction has been retrieved
    // - returns FALSE on any connection error - check LastErrorMessage and
    // LastErrorException to find out the exact connection error
    function ServerTimestampSynchronize: boolean;

so how can I reconnect to the rest when I get an error calling ServerTimestampSynchronize method. I can't find the Close method in TSQLRestClientURI.

connector := TSQLHttpClientWebsockets.Create(AnsiString(host), AnsiString(port), serverAccess, ssl, '', '', 5000, 5000, 10000);

#49 Re: mORMot Framework » Interfaced Based Methods - Sending attachments » 2020-12-09 21:39:04

Are you sure that I don't have to register record? Look at demo 37 , file ServFishShopTypes.pas

type
  TFish = packed record
    Name: RawUTF8;
    Price: currency;
    PictureURI: RawUTF8;
    ID: variant;
  end; // TSQLTable DynArraySave()
  TFishList = array of TFish;


initialization
  TJSONSerializer.RegisterCustomJSONSerializerFromText([
    TypeInfo(TFish), _TFish,
    TypeInfo(TFishDetailed), _TFishDetailed
    ])

#50 Re: mORMot Framework » Interfaced Based Methods - Sending attachments » 2020-12-09 21:02:01

OK, but where is an information how to declare the list of attachments (array or dynarray or collection)?

Board footer

Powered by FluxBB