Skip to content

Real-time library for sending events to Cityline clients. Deeply inspired by server sent events but initiated via posts which allow a much bigger state object with state across multiple producers.

poulfoged/Cityline.Server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

  Build status   Nuget version

Cityline.Server

Use one of the clients to connect to this:

 Client                          This library (dotnet)

 ┌──────────────────────────────┐       ┌──────────────────────────────┐      ┌──────────────────────────────┐
 │                              │       │                              │      │                              ├─┐
 │                              │       │                              │      │                              │ │
 │       Cityline.Client        │◀─────▶│       Cityline.Server        │─────▶│      ICitylineProducer       │ │
 │                              │       │                              │      │                              │ │
 │                              │       │                              │      │                              │ │
 └──────────────────────────────┘       └──────────────────────────────┘      └──┬───────────────────────────┘ │
                                                                                 └─────────────────────────────┘

  - raises events                         - streams data to clients
  - get specific frame                    - calls producers
    (for preloading data)                 - allows state from call to call
  - wait for specific set of frames
    (app initialization)

Demo

See a demo of the server and javascript client here.

Getting started

To get started create a producer. A producer is a stateless class (singleton is fine) that produces an output given a condition. Each producer can store its state in the provided ticket and retrieve it later. The ticket itself is also stored by the clients so even on reconnect we can resume from where we left.

The ticket can also be used to throttle a call by storing a timestamp.

This is a producer that simply sends a ping (a timestamp in this case) every 5 seconds. So in this case the ticket is only used for throtteling.

Returning null from a producer is a way to say "no news at the moment".

   public async Task<object> GetFrame(ITicketHolder ticket, IContext context, CancellationToken cancellationToken = default(CancellationToken))
    {
        var myState = ticket.GetTicket<MyState>();

        if (myState != null)
            if ((DateTime.UtcNow - myState.Created).TotalSeconds < 5)
                return null;

        ticket.UpdateTicket(new MyState());

        // simulate some work
        await Task.Delay(2);

        return new { Ping = DateTime.UtcNow };
    }

You then add a controller to provide an endpoint for the clients to connect to. The CitylineServer class takes a list of producers. (See linked demo to see how to use DI to manage this list).

  [HttpPost]  
  public async Task StartStream(CitylineRequest request, CancellationToken cancellationToken = default(CancellationToken))
  {
      var citylineService = new CitylineServer(providers); 
      var context = new Context { RequestUrl = new Uri(Request.GetEncodedUrl()), User = User };
      Response.Headers.Add("content-type", "text/event-stream");
      await citylineService.WriteStream(Response.Body, request, context, cancellationToken);
  } 

The context object customized to provide further info (like headers) to the producers. It already contains current user and url.

Install

Simply add the NuGet package:

PM> Install-Package Cityline.Server

About

Real-time library for sending events to Cityline clients. Deeply inspired by server sent events but initiated via posts which allow a much bigger state object with state across multiple producers.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages