#1 Re: mORMot 1 » WEB authentication using MORMOT » 2023-03-31 08:02:09

claudneysessa wrote:

Look, to be honest I expected a little more from a support FORUM for such a cool tool.

If I demonstrated the step by step and with examples of what I generated there in my POST it means that I read the manual and implemented it but I am having difficulties. Common thing because MORMOT is a very complex tool and with many details.

Well, I can't count on SUPPORT I'll follow and try to solve it my way, but here's my frustration because the manual talks very vaguely about the subject, some may have this power of abstraction to solve others, they don't.

A little empathy is lacking in wanting to help others.

Without further ado and thank you for your attention.

I know what you're feeling, I had the same problem on this forum and couldn't find the solution that stopped my progress. Everyone suggest me the holy documentation that I don't understand and it does not show the real solutions. I hate documentation, a lot of simple samples is enough in many other projects such as DevExpress, DMVC and many many more. Does someone read DevExpress documentation to start making cool apps ?? No visual components, no real support, very slow responses, hard developing for every stupid projects, no simple swagger integration... Finally I moved to DMVC and made the same project in 1 month comparing to almost 1 year in mORmot framework, I also actively joined their community - EventSource implementation.

#2 mORMot 1 » 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.

#3 mORMot 1 » Websocket - message order » 2022-11-24 10:16:11

radexpol
Replies: 1

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?

#5 Re: mORMot 1 » [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"?

#6 Re: mORMot 1 » 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.

#7 Re: mORMot 1 » 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?

#8 mORMot 1 » 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?

#9 mORMot 1 » 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.

#10 mORMot 1 » 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).

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

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

#12 Re: mORMot 1 » 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

#13 Re: mORMot 1 » 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);

#14 mORMot 1 » 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

#15 Re: mORMot 1 » 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)

#16 Re: mORMot 1 » 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.

#17 Re: mORMot 1 » 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

#18 Re: mORMot 1 » 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.

#19 mORMot 1 » 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;

#20 Re: mORMot 1 » 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;

?

#21 Re: mORMot 1 » 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 ?

#22 Re: mORMot 1 » 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?

#23 mORMot 1 » 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?)

#24 Re: mORMot 1 » 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?

#25 Re: mORMot 1 » 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 ?

#26 Re: mORMot 1 » 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.

#27 mORMot 1 » 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.

#28 mORMot 1 » [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.

#29 mORMot 1 » 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?

#30 Re: mORMot 1 » 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.

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

radexpol
Replies: 4

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.

#32 Re: mORMot 1 » 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.

#33 mORMot 1 » 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.

#34 Re: mORMot 1 » 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.

#35 Re: mORMot 1 » 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.

#36 mORMot 1 » 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

#37 mORMot 1 » 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}

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

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

#39 mORMot 1 » 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"&

#40 Re: mORMot 1 » Keep Alive » 2021-04-21 21:44:42

How can I change ping time?

#41 mORMot 1 » 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;

#42 Re: mORMot 1 » 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.

#43 mORMot 1 » 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.

#44 Re: mORMot 1 » 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.

#45 Re: mORMot 1 » 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);

#46 mORMot 1 » 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);

#47 Re: mORMot 1 » 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?

#48 Re: mORMot 1 » 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?

#49 mORMot 1 » 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);

#50 Re: mORMot 1 » 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
    ])

Board footer

Powered by FluxBB