Search code examples
c#server-sent-eventsevent-stream

Listening to text/event-stream using C#


I am writing a C# class to wrap around a simple web service. The RESTful stuff was easy to wrap up, but now I need to raise an event when something on the server changes.

I've set the server up to make an event stream available, but I don't know how to pick up the stream in C#.

Currently I'm dong something like this:

public class ServiceWrapper
{
    private readonly wc = new WebClient();

    public ServiceWrapper()
    {
        wc.OpenReadAsync(new Uri(UriOfEvent));
        wc.OpenReadCompleted += ServerEventOccurs;
    }

    private void ServerEventOccurs(object sender, OpenReadCompletedEventArgs args)
    {
        using (var sr = new StreamReader(args.Result))
        {
            var message = ParseStream(sr);
            RaiseServerEventOccurred(message);
        }

        wc.OpenReadAsync(new Uri(UriOfEvent));
    } 

    //usual code for declaring and raising ServerEventOccurred event
}

In my test the event gets picked up once, but not twice. The event on the server is essentially a switch - something happens and it goes on, something else happens and it goes off. I know the switching works, because I've hooked the event stream up to a normal web page to test it.

How should I be dealing with event streams in C#?

Edit 1: I've updated the code to fix the bug TimVK points out, but the event stream still isn't being picked up the second time it should be.


Solution

  • Doesn't it work when you put your wc as a property in the class instead of creating always a new one in your methods?

    public class ServiceWrapper 
    { 
        WebClient wc {get;set;}
        public ServiceWrapper() 
        { 
            wc = new WebClient(); 
            wc.OpenReadAsync(new Uri(UriOfEvent)); 
            wc.OpenReadCompleted += ServerEventOccurs; 
        } 
     
        private void ServerEventOccurs(object sender, OpenReadCompletedEventArgs args) 
        { 
            using (var sr = new StreamReader(args.Result)) 
            { 
                var message = ParseStream(sr); 
                RaiseServerEventOccurred(message); 
            } 
     
            wc = new WebClient(); 
            wc.OpenReadAsync(new Uri(UriOfEvent)); 
        }  
     
        //usual code for declaring and raising ServerEventOccurred event 
    } 
    

    Then I suppose the event should be raised everytime.