【问题标题】:Enable gzip/deflate compression启用 gzip/deflate 压缩
【发布时间】:2013-05-05 06:51:39
【问题描述】:

我使用ServiceStack(版本 3.9.44.0)作为 Windows 服务(所以我使用 IIS)并且我将它的功能同时用作 API 和服务 Web页面。

但是,当客户端支持压缩时,我无法找到我应该如何启用压缩。

我想象如果客户端的请求包含 Accept-Encoding:gzip,deflate 标头,ServiceStack 会透明地压缩数据,但在返回的响应中我没有看到任何对应的 Content-Encoding:gzip

所以我有几个相关的问题:

  1. 在将 ServiceStack 用作独立服务(无 IIS)的情况下,如何在浏览器接受响应时启用压缩。

  2. 在 C# 客户端的上下文中,我如何类似地确保客户端/服务器之间的通信被压缩。

如果我遗漏了什么,欢迎任何帮助。

谢谢。

【问题讨论】:

    标签: servicestack servicestack-bsd


    【解决方案1】:

    如果您想在您的 API 中启用全局压缩,另一种选择是这样做:

    将此覆盖添加到您的 AppHost:

    public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(ActionContext actionContext)
    {
        return new MyServiceRunner<TRequest>(this, actionContext);
    }
    

    然后像这样实现那个类:

    public class MyServiceRunner<TRequest> : ServiceRunner<TRequest>
    {
        public MyServiceRunner(IAppHost appHost, ActionContext actionContext) : base(appHost, actionContext)
        {
        }
    
        public override void OnBeforeExecute(IRequestContext requestContext, TRequest request)
        {
            base.OnBeforeExecute(requestContext, request);
        }
    
        public override object OnAfterExecute(IRequestContext requestContext, object response)
        {
            if ((response != null) && !(response is CompressedResult))
                response = requestContext.ToOptimizedResult(response);
    
            return base.OnAfterExecute(requestContext, response);
        }
    
        public override object HandleException(IRequestContext requestContext, TRequest request, Exception ex)
        {
            return base.HandleException(requestContext, request, ex);
        }
    }
    

    将调用 OnAfterExecute 并让您有机会更改响应。在这里,我正在压缩任何非空且尚未压缩的内容(以防我在某处使用 ToOptimizedResultUsingCache)。如果需要,您可以更具选择性,但在我的情况下,我都是带有 json 的 POCO 对象。

    参考文献

    【讨论】:

      【解决方案2】:

      对于那些对我自己问题的部分回答感兴趣的人,您可以使用扩展方法ToOptimizedResult(),或者,如果您正在使用缓存ToOptimizedResultUsingCache()

      例如,返回一个压缩的结果:

      public class ArticleService : Service
      {
        public object Get(Articles request) {
          return base.RequestContext.ToOptimizedResult( 
             new List<Articles> { 
                  new Article {Ref = "SILVER01", Description = "Silver watch"},
                  new Article {Ref = "GOLD1547", Description = "Gold Bracelet"}
             });
        }
      }
      

      参考文献

      【讨论】: