简体   繁体   English

提取数据时,ServiceStack MsgPackServiceClient失败,但JsonServiceClient起作用

[英]ServiceStack MsgPackServiceClient fails when fetching data but JsonServiceClient works

I'm playing around with ServiceStack and doing baby steps trying to understand the technology. 我正在与ServiceStack一起玩耍,并做了一些简单的步骤来尝试了解这项技术。

I've got a very simple setup (complete solution is available for download ): 我有一个非常简单的设置(完整的解决方案可下载 ):

  • Stand alone AppHost using ServiceStack (self-hosted) 使用ServiceStack的独立AppHost(自托管)
  • I launch the server 我启动服务器
  • then I query a list of Article data. 然后我查询列表Article数据。

I installed the nuget package for ServiceStack.Pluging.MsgPack and added the reference and properly set the AppHost plugin, as shown in the main() code below. 我为ServiceStack.Pluging.MsgPack安装了nuget包,并添加了引用并正确设置了AppHost插件,如下面的main()代码所示。

The Classes DTO and Service DTO和服务类

These are the data class, DTO and Service classes I use: 这些是我使用的数据类,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"} ,            
        };
    }
}

All this does is allow a client to get a list of 16 dummy Articles . 这一切都是为了让客户获得16 Articles虚拟Articles的列表。

The server and client request 服务器和客户端请求

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();
}

With AppHost defined as: 将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) {  }
}

What happens 怎么了

The call to client.Get(...) fails with a SerializationException saying: 调用client.Get(...)失败,并显示SerializationException
The unpacker did not read any data yet. 解包程序尚未读取任何数据。 The unpacker might never read or underlying stream is empty. 解压缩程序可能永远不会读取或基础流为空。

  • The exception occurs when I use MsgPackServiceClient() with more than 15 records. 当我将MsgPackServiceClient()与超过15条记录一起使用时,会发生异常。
    Strangely enough, if I return 15 or less Articles instances, it works. 奇怪的是,如果我返回15个或更少的Articles实例,它将起作用。

  • If I use JsvServiceClient() or JsonServiceClient() instead, I have no problem returning thousands of records. 如果我改用JsvServiceClient()JsonServiceClient() ,则返回数千条记录没有问题。

I really don't know if I'm doing something very wrong or if there is something else at play here. 我真的不知道我是在做错什么,还是在做其他事情。

Additional info and download 附加信息和下载

I'm using VS2012 with ServiceStack 3.9.43 (including the MsgPack plugin) installed through nuget. 我正在将VS2012与通过nuget安装的ServiceStack 3.9.43(包括MsgPack插件)一起使用。
The problem occurs regardless of the compilation options (AnyCPU/x86). 无论使用哪种编译选项(AnyCPU / x86),都会出现此问题。 No code optimization enabled (every solution/project option is the default one). 没有启用代码优化(每个解决方案/项目选项都是默认选项)。

You can download the complete solution and try it yourself. 您可以下载完整的解决方案 ,然后自己尝试。

So, I'm not exactly sure what the issue is. 因此,我不确定是什么问题。 It seems to be specific to using the MsgPackServiceClient within the same application of the AppHost. 似乎特定于在AppHost的同一应用程序中使用MsgPackServiceClient。 If you make the request from the browser to something like http://localhost:8883/Articles?format=x-msgpack it appears to work. 如果您从浏览器向http://localhost:8883/Articles?format=x-msgpack之类的请求发出请求,它似乎可以正常工作。

Writing a test (like one at the bottom) seems to confirm that the MessagePackSerializer is working properly. 编写测试(如底部的测试)似乎可以确认MessagePackSerializer正常运行。

Adding a response filter (below) that writes to OutputStream seems to correct your issue. 添加一个写入OutputStream的响应过滤器(如下)似乎可以解决您的问题。 I tried with 16 and 32 records in the list. 我尝试使用列表中的16和32条记录。

Hope this helps. 希望这可以帮助。

    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 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();
    }

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

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