#1 2018-09-12 09:34:31

cybexr
Member
Registered: 2016-09-14
Posts: 81

sicClientDriven mode Client re-connect problem

Backend server maybe restarted without notifcation to clients.  so just after server restart,  the next-client-request contains the old-ClientDrivenID will get an resonse-error: 403 Forbidden.
My first try was on restclient.OnAuthentificationFailed event,  add some code:

   fClient.SetUser('User','synopse');
   fClient.ServiceContainer.Info(TypeInfo(IRemoteSQL)).Get(fService);
   Result:= False;

but meets some curious problem, about the ClientDrivenID, seems later request totally ignore-ClientDrivenID.  And finally I lost in TServiceFactoryClient.InternalInvoke:

...
  if (status=HTTP_UNAUTHORIZED) and (clientDrivenID<>'') and
     (fInstanceCreation=sicClientDriven) and (aClientDrivenID<>nil) then begin
    {$ifdef WITHLOG}
    log.Log(sllClient,'% -> try to recreate ClientDrivenID',[resp],self);
    {$endif}
    aClientDrivenID^ := 0;
    uri := baseuri;
    fRest.ServicesRouting.ClientSideInvoke(uri,aMethod,aParams,'',sent);
    status := aClient.URI(uri,'POST',@resp,@head,@sent).Lo;
  end;
...

Here , can we have an optional recreate judgement? or some callbacks?

...
  if aServiceCustomAnswer=nil then begin
   ....
  end else begin
    // custom answer returned in TServiceCustomAnswer
    fRest.InternalLog('TServiceCustomAnswer(%) returned status=% len=%',
      [head,status,length(resp)],sllServiceReturn);
    aServiceCustomAnswer^.Status := status;
    aServiceCustomAnswer^.Header := head;
    aServiceCustomAnswer^.Content := resp;
    if aClientDrivenID<>nil then
      aClientDrivenID^ := 0;
  end;
...

And here,  why just let aClientDrivenID^ := 0 ?  My backend-service function returned TServiceCustomAnswer. it seems this line occurs the problem.

Offline

#2 2018-09-12 10:58:10

pvn0
Member
From: Slovenia
Registered: 2018-02-12
Posts: 211

Re: sicClientDriven mode Client re-connect problem

sounds like it's working as intended, you get a 403 Forbidden because the interface is no longer valid, at this point you should try to resolve the service again on client side like

if FClient.Services.Resolve(IRemoteSQL, FService) then {...} 

Offline

#3 2018-09-13 02:07:43

cybexr
Member
Registered: 2016-09-14
Posts: 81

Re: sicClientDriven mode Client re-connect problem

thanks for reply pvn0,  tried but failed. Add FClient.Services.Resolve on OnAuthentificationFailed  event, then framework will post _free_  _instances_ , but both will get 403 Forbidden. Guess may because after server restart, client will need auth agian.

#1 http://10.20.40.254:8888/root/RemoteSQL.ExeBin/2?session_signature=6ba3482b00090f5843ebd140   Get 200 OK, then server restarted.
#2 http://10.20.40.254:8888/root/RemoteSQL.ExeBin/2?session_signature=6ba3482b00090f7180a5ae84   Get 403 Forbidden
#3 http://10.20.40.254:8888/root/RemoteSQL._free_/2?session_signature=6ba3482b00090f7a01c51054  FClient.Services.Resolve , but Get 403 Forbidden
#4 http://10.20.40.254:8888/root/RemoteSQL._instance_?session_signature=6ba3482b00090f7a0909a6ce   FClient.Services.Resolve , but Get 403 Forbidden

Currently, I'm force FService:=nil and FreeAndNil(RestClient), then wait my app recreate Restclient&doInit on next-request.

Offline

Board footer

Powered by FluxBB