我正在玩 ServiceStack 并尝试了解这项技术。

我有一个非常简单的设置(完整的解决方案是 available for download ):

  • 使用 ServiceStack(自托管)的独立 AppHost
  • 我启动服务器
  • 然后我查询 Article 数据列表。

  • 我为 ServiceStack.Pluging.MsgPack 安装了 nuget 包并添加了引用并正确设置了 AppHost 插件,如下面的 main() 代码所示。

    类 DTO 和服务

    这些是我使用的数据类、DTO 和服务类:

    public class Article : IReturn<Article>
    {
        public string AR_REF { get; set; }
        public string AR_DESIGN { get; set; }
        public string AR_CODEBARRE { get; set; }
        public string FA_CODEFAMILLE { get; set; }
        public string CT_INTITULE { get; set; }
    }
    
    public class Articles : IReturn<List<Article>> { }
    
    public class ArticleService : Service
    {
        public List<Article> Get(Articles request) {
            return new List<Article>() {
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
            };
        }
    }
    

    所有这些都是允许客户端获取 16 个虚拟 Articles 的列表。

    服务器和客户端请求

    static void Main() {
        var appHost = new AppHost();
        appHost.Plugins.Add(new MsgPackFormat());
        appHost.Init();
        appHost.Start("http://localhost:8883");
    
        // Fails when calling client.Get()
        var client = new MsgPackServiceClient("http://localhost:8883");
        List<Article> response = client.Get(new Articles());
    
        appHost.Stop();
    }
    

    AppHost 定义为:

    public class AppHost : AppHostHttpListenerBase
    {
        static readonly ConfigurationResourceManager AppSettings = new ConfigurationResourceManager();
        public AppHost() : base("Test", typeof(Article).Assembly) { }
        public override void Configure(Funq.Container container) {  }
    }
    

    怎么了
    client.Get(...) 调用失败,SerializationException 说:
    解包器还没有读取任何数据。解包器可能永远不会读取或底层流为空。
  • 当我使用超过 15 条记录的 MsgPackServiceClient() 时会发生异常。
    奇怪的是,如果我返回 15 个或更少的 Articles 实例,它就可以工作。
  • 如果我改用 JsvServiceClient()JsonServiceClient(),则返回数千条记录没有问题。

  • 我真的不知道我是否做错了什么,或者这里是否有其他东西在起作用。

    附加信息和下载

    我将 VS2012 与通过 nuget 安装的 ServiceStack 3.9.43(包括 MsgPack 插件)一起使用。
    无论编译选项如何 (AnyCPU/x86),都会出现问题。未启用代码优化(每个解决方案/项目选项都是默认选项)。

    您可以 download the complete solution 并自己尝试。

    最佳答案

    所以,我不确定是什么问题。它似乎特定于在 AppHost 的同一应用程序中使用 MsgPackServiceClient。如果您从浏览器向 http://localhost:8883/Articles?format=x-msgpack 之类的内容发出请求,它似乎可以工作。

    编写一个测试(如底部的一个)似乎确认 MessagePackSerializer 工作正常。

    添加写入 OutputStream 的响应过滤器(如下)似乎可以解决您的问题。我尝试了列表中的 16 和 32 条记录。

    希望这可以帮助。

        appHost.ResponseFilters.Add((httpReq, httpRes, dto) =>
        {
            if (httpReq.ResponseContentType == ContentType.MsgPack)
            {
                using (var ms = new MemoryStream())
                {
                    var serializer = MessagePackSerializer.Create(dto.GetType());
                    serializer.PackTo(Packer.Create(ms), dto);
    
                    var bytes = ms.ToArray();
    
                    var listenerResponse = (HttpListenerResponse)httpRes.OriginalResponse;
                    listenerResponse.OutputStream.Write(bytes, 0, bytes.Length);
                    httpRes.EndServiceStackRequest();
                }
            }
        });
    

    MessagePackSerializer 测试
        [Test]
        public void test()
        {
            var arts = new List<Article>() {
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
                new Article() {AR_CODEBARRE = "987654", AR_REF = "1002.ARRGHHH", AR_DESIGN = "BLAH BLAH TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "50FAM"} ,
                new Article() {AR_CODEBARRE = "123456", AR_REF = "515.VEROTEST", AR_DESIGN = "THIS IS A TEST", CT_INTITULE = "ACME", FA_CODEFAMILLE = "10FAM"} ,
            };
    
            var serializer = MessagePackSerializer.Create<List<Article>>();
    
            var ms = new MemoryStream();
            serializer.PackTo(Packer.Create(ms), arts);
            ms.Position = 0;
            try
            {
                var obj = serializer.Unpack(ms);
                Assert.IsNotNull(obj);
            }
            catch (Exception ex)
            {
                throw ex;
            }
    
            ms.Close();
        }
    

    关于c# - 获取数据时 ServiceStack MsgPackServiceClient 失败,但 JsonServiceClient 有效,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16238889/

    10-13 08:33