【问题标题】:Delphi DataSnap RestDelphi DataSnap Rest
【发布时间】:2017-06-07 16:18:33
【问题描述】:

我正在使用 REST 和 json 运行一些 Datasnap 测试。

Delphi 自己创建的 Unit ServerMethods 中有“ReverseString”功能,但是,我怎么知道是谁发送的呢?

我想保留调用此方法的客户的信息日志。

我知道它可以作为参数传递,但客户端有责任将此信息传递给我,我不希望这样,假设该方法将是公开的,并且多个客户端将触发此信息.如果我不通过服务器的控制直接获取信息,我很容易失去这种控制。

我在网上发现,在ServerConteiner单元中,有一个“DSServer”对象,这个对象有一个名为“OnConnect”的事件,所以可以得到如下sa数据:

Procedure TServerContainer1.DSServer1Connect (
  DSConnectEventObject: TDSConnectEventObject);
Begin
  DSConnectEventObject.ChannelInfo.ClientInfo.IpAddress;
  DSConnectEventObject.ChannelInfo.ClientInfo.ClientPort;
  DSConnectEventObject.ChannelInfo.ClientInfo.Protocol;
  DSConnectEventObject.ChannelInfo.ClientInfo.AppName;
End;

但我无法在 ServerMethods.ReverseString 中找到如何获取这些数据...

我认为处理是在服务器上的线程中进行的,所以我不能将此值作为全局值传递,因为它可以从其他同时连接的连接中获取信息。

在方法ReverseString中,我尝试如下:

Var
    ADSServerClass: TDSServerClass;
Begin
  ADSServerClass: = TDSServerClass (GetOwner);
  TDSServer (ADSServerClass.Server). ???
  // I got to the server, but I can not find it, and I do not know if it is this way to find the data of who is requesting me to execute the ReverseString
End;

【问题讨论】:

  • 如果您在 Delphi Samples\Object Pascal\DataSnap 文件夹中搜索 - Files in Files for ReverseString,它将带您到各种调用 ReverseString 方法的演示。另外,如果你在谷歌上搜索'delphi "servermethods" 教程,你会发现类似这样的内容:youtube.com/watch?v=C8iqCk4O6Tg
  • 我曾尝试做类似的事情但失败了。 “连接级别”信息(servercontainerunit)在“应用程序级别”(servermethodsunit)中不可用。

标签: rest delphi datasnap


【解决方案1】:

服务器端会话管理是一种解决方案:DataSnap 的一项高级功能。当客户端连接到 DataSnap 服务器时,会创建一个会话。此会话由 TDSSession 实例表示。

在您放置的会话对象中,例如 ip-address。在服务器方法中,您可以从会话对象中读取特定客户端连接的信息。

http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Server_Side_Session_Management

【讨论】:

    【解决方案2】:

    问候,

    解决方案:

    Delphi XE5 Rest Datasnap Server. Getting Client IP Address

    var
      Session: TDSSession;
      Protocol, IpAddress, AppName: string;
    begin
      Session := TDSSessionManager.GetThreadSession;
      Protocol := Session.GetData('CommunicationProtocol');
      IpAddress := Session.GetData('RemoteIP');
      AppName := Session.GetData('RemoteAppName');
    end;
    

    【讨论】:

    • 遗憾的是,这在 Delphi 10.1 上不起作用。这些变量总是空的 :-(.
    • 您好,我在文章开头引用的变量是空的,请查看写有“解决方案”的帖子,或访问我博客上发布的解决方案:blog.atlabs.com.br/2017/06/… 它正在工作,我'我正在使用它。
    【解决方案3】:

    一个非常肮脏的解决方案是在你的 ServerContainer 上创建线程全局变量

    threadvar
      IpAddress: string;   
      ClientPort: integer;
      Protocol: string;
      AppName: string;
    

    因此您现在可以使用这些变量,您将看到每个线程/连接的一组独立值。

    threadvar变量的问题是你的连接完成时没有清空,可能导致内存泄漏。

    因此,为了避免这些泄漏,您需要在 TMethods 数据模块被销毁时手动清除它们。

    procedure TMyMethods.DataModuleDestroy(Sender: TObject);
    begin
      if DatabaseCn.Connected then DatabaseCn.Close;
      IpAddress := '';
      ClientPort := 0;
      Protocol := '';
      AppName := '';
    end;
    

    我确信它们是更优雅的解决方案,但如果没有其他人提供更好的选择,您可以使用此替代方案。

    【讨论】:

    • 谢谢,但是这个想法是让DataSnap服务器作为windows服务保留,如果内存累积,我以后会有问题。我也在我的环境中尝试了一些项目,也公开了。
    猜你喜欢
    • 2021-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-01
    • 2012-09-03
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    相关资源
    最近更新 更多