Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Datasnap and SocketError

I have a datasnap server with a vcl forms client. From the client, how can I handle if the server has been say shutdown and restarted with existing client connections? This scenario raises a 10053 EIdSocketError exception.

To replicate, I run up both Server and Client, make a call to the server (I use methods exposed via the DataSnap proxy generator) which succeeeds. I then shut down the server (eg Close the application) and restart it. I then attempt to make a call to the server again.

eg: CLIENT call

    sm := TsvrPolicySearchClient.Create(datClientDB.SQLConnection1.DBXConnection);
    try
      ds := sm.SearchPolicyByPolicy(40, WCRef, '', 3);
      dspPolicyGroup.DataSet := ds;

      if cdsPolicyGroup.Active then
        cdsPolicyGroup.Refresh
      else
        cdsPolicyGroup.Open;

    finally
      sm.Free;
    end;

dspPolicyGroup is a TDataSetProvider and cdsPolicyGroup is a TClientDataSet (I just use it locally to "store" my TDataSet result).

SERVER

function TsvrPolicySearch.SearchPolicyByPolicy(AClientId: Integer; WCRefNum, ClientRef: string; SearchMethod: Integer): TDataSet;
begin
  spPolicyByWCRef.Close;
  spPolicyByWCRef.ParamByName('p_client').AsInteger := AClientId;
  spPolicyByWCRef.ParamByName('p_search_method').AsInteger := SearchMethod;
  spPolicyByWCRef.ParamByName('p_wc_refno').AsString := WCRefNum;
  spPolicyByWCRef.Open;
  Result := spPolicyByWCRef;
end;

I would think this is regularly encountered by people seeing that it's quite easy to replicate. Should I place a "Test Connection" call or something first (such as a method TestConnection) before each call to check for EIdSocketError (and equivalent) and handle? Or is it more a design flaw perhaps?

Thanks

like image 357
Jason Avatar asked Aug 13 '12 05:08

Jason


2 Answers

My scenario:

  • Client application connect to DataSnap Server (TCP/IP, remote server)
  • Client request a DataSet (using DataSnap server methods). TClientDataSet
  • Client downloaded dataset
  • Server shutdown (taskkill, close application no matters)
  • Client request a DataSet againt (ehhrrr Socket Error)

Solution:

  • On client I catch exception (AppEvents.OnException)
  • Recognize that is Socket error from connection to DataSnap server
  • I show dialog window with information that connection is lost. User can click "RETRY" - if so,
    • Free and re-create DataSnap client module and initialize connection
    • Try to request dataset (special dataset for connection test) if application catch exception entire process works from the beginning.

After this operation my Client re-connect to DataSnap server and can request dataset using new TCP/IP connection. Of course user can close dialog, but then application is turn off.

I think this can help you. I tried many others solutions but this proved to be the best. Moreover algorithm also supports the loss of connection with the client's fault.

like image 191
robertw Avatar answered Sep 20 '22 23:09

robertw


The easiest workaround for this problem is to change the TDSServerClass LifeCycle attribute to Invocation. This will cause you to have a stateless server, and the server will create a new session per request. But, you will be able to close and reconnect the server without interrupting the clients connection.

like image 42
Troy Harris Avatar answered Sep 20 '22 23:09

Troy Harris