【问题标题】:Delphi REST Server, Android Client using compressionDelphi REST Server, Android Client 使用压缩
【发布时间】:2013-01-29 06:59:29
【问题描述】:

我们正在构建一个 Delphi REST 服务器,为原生 Android 应用程序提供相当大的数据块(每个请求 1.5MB,其中有很多)。一切正常,除了这种情况下的数据大小会出现问题,导致我们环境中的传输时间过长(移动数据速率有限)。我尝试在DSHTTPWebDispatcher 上添加ZLibCompression 过滤器,但响应只会以未压缩的文本/html 的形式再次返回。

有没有什么办法可以强制服务器在 dispatch 前使用作为事件添加的过滤器?

服务器是使用 Delphi XE3 构建的。

【问题讨论】:

  • 您的请求的接受编码标头值是多少?
  • 你如何发送数据(方法公司)?
  • 能否也显示客户端Android代码?
  • 感谢您的提问...客户是谁并不重要,它应该可以被任何操作系统中的应用程序使用。这里的问题是首先让实际压缩工作,并正确设置内容类型。我已经弄清楚了,很快就会在这里发布结果。

标签: delphi rest datasnap http-compression delphi-xe3


【解决方案1】:

我已经设法找出在 DataSnap 项目中添加压缩和相关标头更改的位置。

这里的关键是 TWebModule 类。如果使用向导创建新项目,则会构造 TWebModule 类的默认实现,其中包含 BeforeDispatch、AfterDispatch 等的事件属性。 这里的命名是指将传入的请求分派到将要处理的地方的动作。因此,BeforeDispatch 在请求到达时发生,一些处理发生在服务器上,AfterDispatch 在响应发送回调用者之前触发。

因此,如果想要在事后修改构造的响应,则使用 AfterDispatch 是正确的事件。这可以包括对内容和标题的更改。

在 AfterDispatch 事件中:

procedure TWebModule1.WebModuleAfterDispatch(
  Sender: TObject;
  Request: TWebRequest; 
  Response: TWebResponse;
  var Handled: Boolean);
var

srcbuf, destbuf : TBytes;
str : string;

begin
  str := Response.Content;

  //prepare byte array
  srcbuf := BytesOf(str);

  //compress to buff (System.ZLib)
  ZCompress(srcbuf, destbuf, zcMax);

  //prepare responsestream and set content encoding and type
  Response.Content := '';
  Response.ContentStream := TMemoryStream.Create;
  Response.ContentEncoding := 'deflate';
  Response.ContentType := 'application/json';

  //current browser implementations incorrectly handles the first 2 bytes 
  //of a ZLib compressed stream, remove them
  Response.ContentStream.Write(@(destbuf[2]),length(destbuf)-2);
  Response.ContentLength := (length(destbuf))-2;
end;

不是很花哨,可以根据发回的内容启用/禁用压缩,但对于我们的实现,我们保持简单。

这适用于 Fiddler 和可以处理 deflate 的浏览器 100%。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-29
    • 2017-03-17
    相关资源
    最近更新 更多