简体   繁体   English

德尔福DataSnap Rest

[英]Delphi DataSnap Rest

I'm running some Datasnap tests with REST and json. 我正在使用REST和json运行一些Datasnap测试。

There in Unit ServerMethods, which Delphi itself creates, has the "ReverseString" function, but well, how do I know who sent it? Delphi自己创建的UnitServerMethods中具有“ ReverseString”功能,但是,我怎么知道是谁发送的呢?

I would like to keep a log of information from the clients who called this method. 我想保留来自调用此方法的客户端的信息日志。

I know it could be passed as a parameter, but it would be the responsibility of the client to pass this information to me, which I do not want, let's say the method would be public and several clients would be triggering this information. 我知道可以将其作为参数传递,但是由客户负责将这些信息传递给我,这是我不希望的,我说这种方法是公开的,并且有几个客户端将触发此信息。 I can easily lose this control, if I do not get the information directly by the control of the server. 如果我没有通过服务器的控制直接获得信息,则很容易失去此控制。

I found on the web, that in the ServerConteiner unit, has a "DSServer" object, this object has an event called "OnConnect", so it can get the following sa data: 我在网上发现,在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;

But I am not able to find how there in ServerMethods.ReverseString I can get this data ... 但是我无法在ServerMethods.ReverseString中找到该如何获取此数据...

I believe that the processing is in thread on the server, so I can not pass this value as global, because it can pick up information from other simultaneous connections. 我相信处理是在服务器上的线程中进行的,所以我不能将此值作为全局值传递,因为它可以从其他同时连接中获取信息。

In the method, ReverseString, I tried as follows: 在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;

Server side session management is a solution: an advanced feature of DataSnap. 服务器端会话管理是一种解决方案:DataSnap的高级功能。 When a client connects to a DataSnap server, a session is created. 客户端连接到DataSnap服务器时,将创建一个会话。 This session is represented with a TDSSession instance. 该会话用TDSSession实例表示。

In a session object you put for example ip-address. 在会话对象中,您放置了例如ip-address。 In server method you can read information from session object for specific client connection. 在服务器方法中,您可以从会话对象中读取特定客户端连接的信息。

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

Regards, 问候,

solution: 解:

Delphi XE5 Rest Datasnap Server. Delphi XE5 Rest Datasnap服务器。 Getting Client IP Address 获取客户端IP地址

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

A very dirty solution is to create thread global variables on your ServerContainer 一个非常肮脏的解决方案是在ServerContainer上创建线程全局变量

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

So you can now use these variables and you will see an independent set of values per thread/connection. 因此,您现在可以使用这些变量,并且每个线程/连接都会看到一组独立的值。

The problem of threadvar variables is that there are not emptied when your connection finishes, potentially leading to memory leaks. threadvar变量的问题是,连接完成后没有清空,可能导致内存泄漏。

So to avoid those leaks you will neeed to clear them manually when your TMethods datamodule is destroyed. 因此,为避免这些泄漏,您需要在TMethods数据模块被破坏时手动清除它们。

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

I'm certain that they are far more elegant solutions, but you could use this alternative if no one else provides a better option. 我确信它们是更优雅的解决方案,但是如果没有其他人提供更好的选择,则可以使用此替代方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM