c# – ServiceStack MsgPackServiceClient在获取数据但JsonServiceClient工作时失败

我正在玩ServiceStack,并试图了解这项技术.

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

>使用ServiceStack独立AppHost(自托管)
>我启动服务器
>然后我查询文章数据列表.

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

课程DTO和服务

这些是我使用的数据类,DTO和Service类:

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个虚拟文章的列表.

服务器和客户端请求

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个或更少的文章实例,它就可以了.
>如果我使用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();
    }
点赞