带Datasnap Rest和关闭会话的TStream

带Datasnap Rest和关闭会话的TStream,rest,delphi,session,datasnap,Rest,Delphi,Session,Datasnap,我构建了datasnap REST应用程序,无法关闭会话 例如,如果我在web浏览器中调用我的URL 4次: http://127.0.0.1:4445/REST/image?json=false 共有4节课开放 以下是我的功能: function TV1.TestImage:TStream; var ContentType : String; FileStream : TFileStream; begin FileStream := TFileStream.Create('C:\san

我构建了datasnap REST应用程序,无法关闭会话

例如,如果我在web浏览器中调用我的URL 4次:
http://127.0.0.1:4445/REST/image?json=false

共有4节课开放

以下是我的功能:

function TV1.TestImage:TStream;
var
ContentType : String;
FileStream : TFileStream;
begin
    FileStream := TFileStream.Create('C:\santiago.jpg', fmOpenRead or fmShareDenyNone);
    ContentType := 'image/jpg';

    GetInvocationMetadata.ResponseContentType := ContentType;
    ContentTypeHeaderToUse := ContentType;
    GetInvocationMetadata().ResponseCode := 200;

    result := FileStream;

    //Can't call CloseSession with TStream, pointer exception
    //GetInvocationMetaData.CloseSession := True;

end;
我在Dispatch后使用
WebModuleAfterDispatch
,如下所示:

  procedure TWebModule2.WebModuleAfterDispatch(Sender: TObject;
  Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
  var session : TDSSession;
  begin
      response.FreeContentStream := true;

      if ContentTypeHeaderToUse<>'' then begin
          Response.ContentType := ContentTypeHeaderToUse;
          ContentTypeHeaderToUse := ''; // Reset global variable
      end;

  end;
过程TWebModule2.WebModuleAfterDispatch(发送方:TObject;
请求:TWebRequest;响应:TWebResponse;处理的变量:Boolean);
var会话:TDSSession;
开始
response.FreeContentStream:=true;
如果ContentTypeHeaderToUse为“”,则开始
Response.ContentType:=ContentTypeHeaderToUse;
ContentTypeHeaderToUse:='';//重置全局变量
结束;
结束;
如您所见,
GetInvocationMetaData.CloseSession:=True不能在此处使用


您知道如何在发送TStream后关闭会话吗?

在REST服务器上,我更喜欢返回base64字符串,它比Delphi TStream(字节数组)的JSON表示更容易处理客户端应用程序

Soap.EncdDecd单元上的EncodeBase64函数非常容易进行转换:

function TV1.TestImage:string;
var MemoryStream: TMemoryStream;
begin
  MemoryStream := TMemoryStream.Create;
  MemoryStream.LoadFromFile('C:\santiago.jpg');
  Result := EncodeBase64(MemoryStream.Memory, MemoryStream.Size);
  MemoryStream.Free; // Now you can free the Stream yourself
end;
另一个好处是,您现在可以释放流,而不必依赖Datasnap来完成。因此,您应该能够在没有指针异常的情况下手动关闭连接,并解决多个会话保持打开的问题

您可以在web应用程序上直接使用该base64图像字符串。您只需要在标记的开头添加它们的类型

例如:

<img src="data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAYAAADE6YVjAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MEVBMTczNDg3QzA5MTFFNjk3ODM5NjQyRjE2RjA3QTkiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MEVBMTczNDk3QzA5MTFFNjk3ODM5NjQyRjE2RjA3QTkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowRUExNzM0NjdDMDkxMUU2OTc4Mzk2NDJGMTZGMDdBOSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowRUExNzM0NzdDMDkxMUU2OTc4Mzk2NDJGMTZGMDdBOSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PjjUmssAAAGASURBVHjatJaxTsMwEIbpIzDA6FaMMPYJkDKzVYU+QFeEGPIKfYU8AETkCYI6wANkZQwIKRNDB1hA0Jrf0rk6WXZ8BvWkb4kv99vn89kDrfVexBSYgVNwDA7AN+jAK3gEd+AlGMGIBFDgFvzouK3JV/lihQTOwLtOtw9wIRG5pJn91Tbgqk9kSk7GViADrTD4HCyZ0NQnomi51sb0fUyCMQEbp2WpU67IjfNjwcYyoUDhjJVcZBjYBy40j4wXgaobWoe8Z6Y80CJBwFpunepIzt2AUgFjtXXshNXjVmMh+K+zzp/CMs0CqeuzrxSRpbOKfdCkiMTS1VBQ41uxMyQR2qbrXiiwYN3ACh1FDmsdK2Eu4J6Tlo31dYVtCY88h5ELZIJJ+IRMzBHfyJINrigNkt5VsRiub9nXICdsYyVd2NcVvA3ScE5t2rb5JuEeyZnAhmLt9NK63vX1O5Pe8XaPSuGq1uTrfUgMEp9EJ+CQvr+BJ/AAKvAcCiAR+bf9CjAAluzmdX4AEIIAAAAASUVORK5CYII=">


您真的需要进行会话吗?。看起来您应该将DSServerClass的Lifecycle属性设置为Server或Invocation。我试图将我的DSServerClass设置为Server和Invocation,但我遇到了相同的问题,会话数增加了。我的申请不需要会话。从另一个URL来看,我没有这个问题,只是TStream的问题。如何检查活动会话的数量?。使用Lifecycle作为服务器时,并没有会话,所以结果必然是错误的。无论如何,您确定要在REST服务器上返回流吗?您的客户机如何理解该流(它是以字节数组的形式返回的,不是吗?)。在一个非常类似的情况下,我返回一个字符串,用base64表示流内容。您的客户端应用程序更容易处理base64字符串,并且没有任何对象可以由Datasnap机制处理。为了显示活动会话,我使用了
TDSSessionManager.Instance.GetSessionCount
在计时器事件中,lifecycle server中的会话增加,在文档中他们说,调用和会话与Rest应用程序相同。在过去,我们返回了一个ansiString,但是我们遇到了太多像素化的图片显示问题。当我们将delphi更改为10.2时,出现了这个问题,在调用之后,返回的ansisting中的一些字节被更改。base64是否与最新的web浏览器兼容?(IE、Edge、Chrome、Firefox)是的,我们直接使用返回的base64字符串来显示IE、Edge、Chrome和Firefox上的图像。据我所知,我们从未遇到过任何问题。关于会话问题,对不起,我帮不了你,我从来没有遇到过这个问题。