Matt Smith's Blog

Software Engineering related topics

FubuMVC.ServerSentEvents OOTB Support

| Comments

FubuMVC now has support for Server Sent Events (SSE)! I have recently used it for our internal call center dashboard here at Extend Health. Since it’s inception we are now seeing data on the dashboard within seconds of it happening, as opposed to the previous 5 second ajax refresh interval we were doing before.

Out of the box (OOTB) the FubuMVC.ServerSentEvents bottle already does just about everything you need on the server. The only thing you need to implement is a topic for which your events will be coordinated against. A topic is created by inheriting the FubuMVC.ServerSentEvents.Topic class. The topic will be used to coordinate how events are stored and pushed to the connected clients. This is accomplished by overriding the bool Eqauls(object item) and int GetHashCode() methods. See an example below:

SimpleTopic.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
using System;
using FubuMVC.ServerSentEvents;

namespace SomeNamespace
{
    public class SimpleTopic : Topic
    {
        public Guid SomeId { get; set; }

        public override bool Equals(object obj)
        {
            return Equals(obj as SimpleTopic);
        }

        public bool Equals(SimpleTopic other)
        {
            if (ReferenceEquals(null, other)
                return false;

            return ReferenceEquals(this, other) ||
                   SomeId.Equals(other.SomeId);
        }

        public override int GetHashCode()
        {
            return SomeId.GetHashCode();
        }
    }
}

When an event is published or when a client connects, the code will pass through a TopicFamily which is keyed by the topic object you define. A separate channel is created for each topic, which is where the method overrides come in. The diagram below is a BASIC flow of the how events are stored and retrieved:

Basic Flow

Now all you need to do is publish your events and connect a client. You publish events via the IEventPublisher. I will cover the event and how you can customize it in a future post. For now though the ServerEvent class is the basic OOTB event that you can use.

Publishing Events
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using FubuMVC.ServerSentEvents;

namespace SomeNamespace
{
    public class PutHandler
    {
        private IEventPublisher _eventPublisher;

        public PutHandler(IEventPublisher eventPublisher)
        {
            _eventPublisher = eventPublisher;
        }

        public void Execute()
        {
            var topic = new SimpleTopic { SomeId = ...someid...  };
            _eventPublisher.WriteTo(topic, new ServerEvent("1", "data-1"));
        }
    }
}

Now the client can connect to the stream via http://<YOUR HOST>/_events/<TOPIC NAME> which would be http://localhost:8080/_events/SimpleTopic in my example.

The standard protocol for SSE according to W3C specifies that events should follow the format:

W3C SSE Standard
1
2
3
4
5
id: <EVENT ID>\n
event: <EVENT NAME>\n
data: <EVENT DATA>\n
retry: <RECONNECTION TIME>\n
\n

The bottle takes a slightly different stance on this subject. However, you can override it with your own if you like by replacing the IServerEventWriter service with your own implementation. The stream that comes OOTB follows this format:

FubuMVC.ServerSentEvents SSE Standard
1
2
3
4
id: <EVENT ID>/<EVENT NAME>\n
data: <EVENT DATA>\n
retry: <RECONNECTION TIME>\n
\n

This is done so that you only need to setup one event listener on the client, from which you can build up a standard for processing events on the client. Which I plan to describe more in future posts.

Comments