Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
428 views
in Technique[技术] by (71.8m points)

asp.net web api - How to get an IObservable back from Web API

I have a simple Web API which returns an Iobservable. I am using HttpClient to get the Observable so that I can subscribe to it. My problem is the returned Iobservable on subscription sends out an 'empty' result.

SERVER

public IObservable<DataItem> GetDataItems()
{
    return Observable.Generate(0, i => i < 10, i => i + 1, 
        i => new DataItem 
        {
            Id = i, 
            Name = String.Format("Storage{0}",i)
        });
}

CLIENT

public IObservable<DataItem> GetDataItems()
{
    using (HttpClient apiClient = new HttpClient())
    {
        apiClient.BaseAddress = new Uri("http://localhost:9001");
        apiClient.DefaultRequestHeaders.Add("x-user-authentication", "xxxxxx");
        return apiClient
            .GetAsync("api/xxxx/yyyy").Result.Content
            .ReadAsAsync<DataItem>().ToObservable();
    }
}

var source = GetDataItems();

List<DataItem> items = new List<DataItem>();

IDisposable consoleSubscription = source.Subscribe(
            x => Console.WriteLine("{0}:{1}", x.Id, x.Name),
            ex => Console.WriteLine("OnError : {0} ", ex.Message),
            () =>  Console.WriteLine("Encountered End of Stream")
            );
        consoleSubscription.Dispose();

My issue is I am not getting any data back from the server. I get an 'Empty' observable. I wrote a unit test against my controller and it does give back the dataitems.

Any suggestions please help. Unable to understand where I am going wrong. There are no errors on server or client.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're being a little ambitious expecting an IObservable<T> to be streamed over the wire automatically. I'm afraid WebAPI won't do that for you.

What you are seeing is the consequence of the default json serializer outputting the properties of IObservable<T> - and there are none so you get empty braces.

Your unit test works because it's all in-memory - no serialization/deserialization is happening.

There are ways of using HttpResponseMessage's StreamContent property to stream results out which you could bridge to/from IObservable<T> - but it's not really idiomatic WebApi. WebApi's async support is really aimed at asynchronous processing of requests with single-item responses on the server, not at returning continuously streaming events.

Bottom line is that I think WebApi (at least at the time of writing) is the wrong technology choice here. You are far better off looking at SignalR which is purpose built for this sort of scenario, and is included in the current release of ASP.NET. It has both javascript and .NET client support, and you can bridge to IObservable<T> fairly easily. Some people have already looked at this, such as in this post sporting example code.

Some messaging middleware like my-Channels Nirvana (Edit: since bought out by Terracotta and wrapped into Universal Messaging Some example code is available in their documentation.), and CEP solutions like SQL Server StreamInsight have out of box IObservable support too.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...