Tuesday, March 17, 2015

modern day (as of Saint Patrick's Day of 2015) SignalR with OWIN

I set up a SignalR "Hello World" application today, and I could only partially use my old notes as a lot has changed in the second version. I started by making an ASP.NET MVC application in Visual Studio 2013, and then, as detailed here, I had to create an OWIN startup class like so;

using Experiment.Signaling;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin;
using Owin;
[assembly: OwinStartup(typeof(Experiment.Startup))]
namespace Experiment
{
   public partial class Startup
   {
      public void Configuration(IAppBuilder app)
      {
         app.MapSignalR(new HubConfiguration());
         app.MapSignalR<AuthorConnection>("/author");
      }
   }
}

 
 

Alright, one needs an implementation of PersistentConnection too and mine looks like this:

using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
namespace Experiment.Signaling
{
   public class AuthorConnection : PersistentConnection
   {
      protected override Task OnReceived(IRequest request, string connectionId,
            string data)
      {
         return Connection.Broadcast(data);
      }
   }
}

 
 

The rest of the magic happens in JavaScript inside of the view the application first serves up which looks like this:

@{
   Layout = null;
}
<!DOCTYPE html>
<html>
   <head>
      <meta charset="utf-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Experiment</title>
   </head>
   <body>
      <h1>Let's all write a story together...</h1>
      <table>
         <tr>
            <td valign="top">
               <div id="story" style="width:500px; height: 500px;
                     background-color: #00CC00; overflow-y: scroll;">
                  <span style="color:#FFFFFF;">Once upon a time...</span>
               </div>
               <table>
                  <tr>
                     <td nowrap>...and then</td>
                     <td><input type="text" id="contribution" style="width: 400px;" /></td>
                  </tr>
                  <tr>
                     <td></td>
                     <td align="right"><button id="button">Go</button></td>
                  </tr>
               </table>
            </td>
            <td valign="top">
               fun, fun!
            </td>
         </tr>
      </table>
      <script type="text/javascript" src="~/Scripts/jquery-1.10.2.min.js"></script>
      <script type="text/javascript" src="~/Scripts/jquery.signalR-2.2.0.min.js"></script>
      <script type="text/javascript">
         $(function () {
            var conn = $.connection("/author");
            $("#button").click(function () {
               var contribution = $("#contribution").val();
               conn.send(contribution);
               $("#contribution").val("");
            });
            conn.received(function (data) {
               $("#story").append(" " + data + "...");
            });
            conn.start().done(function() {
               if (conn.eventSource) {
                  conn.eventSource.addEventListener('message', function(event) {
                     console.log("EventSource message: " + event.data);
                  });
               }
            });
         });
      </script>
   </body>
</html>

 
 

This all works! Different browsers may both push copy (that all that are listening may see) into the big square green divs seen here:

Addendum 3/18/2015: I should say "one needs an inheritance of PersistentConnection" not "one needs an implementation of PersistentConnection" as one inheritances a class and implements an interface.

No comments:

Post a Comment