SignalR + Nancy with F# hosted on Azure
What you feel if you meet your favourite actor? Feeling is wonderful right? Now, add the your actress in the mixture. Have you said WOW??? How about director? Still heart is beating?!? How about having dinner with them? Nothing can be better than that.
I am having kinda same feeling. It is nothing new that Nancy is dancing quite comfortable with F#. And thanks to Daniel Mohl we are also having templates to get started with Nancy and F#.
Now, I was doing some experiments around it. It was quite good. But how about running it on Owin. hmmm, it works flow less. Nothing more on code side other than few lines here and there. Then I found few projects running SignalR with F#.
I knowing Nancy from a long time. But SignalR, I don’t know anything about it. The only thing I know is that, it is super awesome.
So, first task is to run Nancy on Owin.
Here are simple steps. Using template create a asp.net host with razor project. remove asp.net host and add Owin host using nuget package manager.
Now we need to add startup file.
type Startup() = member x.Configuration(app : Owin.IAppBuilder) = app.UseNancy() |> ignore [<Microsoft.Owin.OwinStartup(typeof<Startup>)>] do ()
And add simple Nancy code. The regular one. Nothing fancy.
There is bootstrap class
type Bootstrapper() = inherit DefaultNancyBootstrapper() override x.ApplicationStartup(container:TinyIoCContainer, pipelines:IPipelines) = StaticConfiguration.DisableErrorTraces <- false base.ApplicationStartup(container,pipelines) ignore()
this is needed to trace the error if anything is there at nancy end.
And our index module
type IndexModule() as x = inherit NancyModule() do x.Get.["/"] <- fun _ -> box x.View.["Index"]
Pretty lame right. But it works.
Now, add Signalr asp.net host nuget package to project. As startup file is already there; no need to create one more. Just minor modification will do.
type Startup() = member x.Configuration(app : Owin.IAppBuilder) = app.MapSignalR().UseNancy() |> ignore
That MapSignalR thing is additionally added. I have just followed Hello World example of real time world. Create a chat application. So, here is the hub to broadcast the message to all users.
type ChatHub() as this = inherit Hub() member x.send (name : string, msg : string) = this.Clients.All?broadcastMessage (name, msg) |> ignore
Now, there is one “?” thing before broadcastMessage function. That is where dynamic method is getting called. F# do not support dynamic by default but there are many work around available. I personally prefer Fsharp.dynamic library. It is better than other code snippets I found over other sites. But that is all personal choice how one like to handle dynamic functions.
So, it is done. Hit F5 and you are ready to go.
What is fun of working with Web if I can’t publish it. But for now with F# web templates it is not possible. And that is known issue. So, if I like to publish it on cloud like azure I need to give git hooks. That is easiest thing I can think off. But road is still not that smooth.
Deployment will break with some weird error. I followed Mark’s article to make it work.
Needed to add below lines to .fsproj file after its own import tags.
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" /> <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v11.0\WebApplications\Microsoft.WebApplication.targets" Condition="true" />
And things are working like anything. No, issues at all.
Nancy |> Razor |> SignalR |> Azure |> F# |> lots of love.
Please give it a shot. If it break somewhere let me know will try to solve it. Any suggestion to make things even better and streamlined are always welcome.
UPDATE: Here is my github repo with updated code. Project created with web express 2013. Also it is deployed over azure.