fsbolero / Bolero

Bolero brings Blazor to F# developers with an easy to use Model-View-Update architecture, HTML combinators, hot reloaded templates, type-safe endpoints, advanced routing and remoting capabilities, and more.
https://fsbolero.io
Apache License 2.0
1.06k stars 53 forks source link

remoting + streaming? #117

Open jmjrawlings-azn opened 4 years ago

jmjrawlings-azn commented 4 years ago

Apologies if this is already covered somewhere - Is there anyway of implementing a remote service that streams results back to the client? eg:

/// Remote service definition.
type BookService =
    {
        /// Returns new books are they are added
        watchBooks: unit -> AsyncSeq<Book> // IObservable<Book> ?
    }

    interface IRemoteService with
        member this.BasePath = "/books"

I see there's a Cmd.ofSub function but can't quite figure out how I'd get the server to continually send back messages with bolero.

wilsoncg commented 4 years ago

I also would like to know. Here are two useful sample reference applications I have found: https://gitlab.com/scitesy/RealTimeBoleroDemo https://github.com/OnurGumus/FBlazorShop

If you find an answer, report back your findings. 😊

Tarmil commented 4 years ago

SignalR would be the way to go for continuous streams. @brikken is working on a SignalR layer, see #111. I presume this will take the form of simple message-sending at first, but it should be possible to build an AsyncSeq layer on top of that.

OnurGumus commented 4 years ago

@J-M-J-R , @wilsoncg , The answer depends on which mode you use. At this point I would recommend using Server mode. This way you can piggyback to existing signalr connection. All you have to do is to keep a reference to the dispatcher property the program. Since all execution happens in server, there is no boundary with elmish and any server side code you have. An example is https://github.com/OnurGumus/TensaiMakoto/blob/c13d650673d249856959789e6e0844ee54b1d41b/TensaiMakoto.Web.BlazorClient/Main.fs#L37

https://github.com/OnurGumus/TensaiMakoto/blob/c13d650673d249856959789e6e0844ee54b1d41b/TensaiMakoto.Web.BlazorClient/Main.fs#L55

This was a prototype of a slideshow I developed for a Japanese friend, where the instructor can switch the slides and it will sync to all students at once. Notice how I keep dispatchers in a static concurrent collection, and when ever I need a message to be dispatched, I just iterate over the the dispatchers. I had to use reflection to acquire dispatcher property of Program but with latest bolero, this property has become public.

Regarding your question about the Cmd.ofSub, note that there many functions in Cmd module, all return different things. Basically Cmd.ofSub means : I do not want to return anything but only pass the current dispatcher to a function.

Once you capture the dispatcher, you can send out of band messages as much as you like, hence it is a sort of Subscription. I hope it helps. Should you need more explanation shoot your questions below.

As for WASM mode, then you have to stick to @Tarmil's suggestion.