Startsidan  ▸  Texter  ▸  Teknikblogg

Anders Hesselbom

Programmerare, skeptiker, sekulärhumanist, antirasist.
Författare till bok om C64 och senbliven lantis.
Röstar pirat.

Anropa alla klienter från ASP.NET

2015-05-29

SignalR är ett ramverk som låter webbklienter prata direkt med webbservern via sockets, och som låter webbservern prata direkt med klienterna på samma sätt. Tack vare SignalR kan du göra funktionsanrop direkt till de användare som för tillfället råkar surfa på din hemsida. SignalR bygger ovanpå ramverket OWIN för ASP.NET.

I detta exempel arbetar jag i Visual Studio 2013 med ett projekt av typen ASP.NET MVC, så jag utgår alltså ifrån Microsofts exempelprogram som levereras som mall i Visual Studio 2013.

signalr1

För att komma igång ska vi:

  • Installera paketet SignalR i projektet.
  • Läsa in JavaScript-filen för SignalR.
  • Koppla SignalR-hubbarna till OWIN.
  • Skapa en hubb.

Därefter är det fritt fram att börja kommunicera!

För att installera SignalR, skriv följade i Package Manager Console:

Install-Package Microsoft.AspNet.SignalR

Eftersom SignalR ligger i version 2.2 när jag skriver detta, så kompletteras mitt program med filerna jquery.signalR-2.2.0.js och jquery.signalR-2.2.0.min.js i mappen Scripts, men tänk på att versionsnumret kan variera om du vill testa detta.

Därefter ska det minimerade scriptet inkluderas i de vyer som SignalR ska fungera på. Jag hade tänkt mig att kunna använda den överallt, så jag lägger in scriptet i Views/Shared/_Layout.cshtml. Vi ska även läsa in det autogenererade scriptet signalr/hubs.

<script type="text/javascript"
   src="~/scripts/jquery.signalR-2.2.0.min.js"></script>

Jag föredrar att flytta upp de script som redan ligger på sidan till dokumentets head-sektion, så att den ser ut så här:

<head>
   <meta charset="utf-8" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>@ViewBag.Title - My ASP.NET Application</title>
   @Styles.Render("~/Content/css")
   @Scripts.Render("~/bundles/modernizr")
   @Scripts.Render("~/bundles/jquery")
   @Scripts.Render("~/bundles/bootstrap")
   <script type="text/javascript"
     src="~/scripts/jquery.signalR-2.2.0.min.js"></script>
   
   @RenderSection("scripts", required: false)
</head>

I nästa steg ska vi koppla SignalR-hubbarna till OWIN. Hubbarna, alltså kommunikationsnaven, har ett client-attribut som används för att prata med klienten och ett server-attribut som används för att prata med servern, och identifieras av adressen “/signalr” om vi inte sagt något annat. För att göra kopplingen behöver vi ha en OWIN Startup class. Högerklicka på ditt projektnamn i Solution Explorer, välj att lägga till en OWIN Startup class. Kalla den för OwinStartup. Det ger oss följande kod:

using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(WebApplication3.OwinStartup))]

namespace WebApplication3
{
   public class Startup
   {
      public void Configuration(IAppBuilder app)
      {
         // For more information on...
      }
   }
}

Ersätt kommentaren i funktionen Configuration med följande anrop:

app.MapSignalR();

Nu har vi gjort de förberedelser som behövs för att kommunicera. Till att börja med tänkte jag att klienten ska få skicka ett meddelande till servern när användaren klickar på en knapp.

Den sista förberedelsen innan vi kan börja är att skapa en hubb. En hubb är en klass som ärver från Microsoft.AspNet.SignalR.Hub. Kontrollera att du har mappen App_Code, annars kan den skapas från menyn som visas när man högerklickar på projektnamnet. Sedan, högerklicka på mappen App_Code och lägg till en klass av typen SignalR Hub Class (v2). Ge den namnet MinTestHub. Det går också att lägga till en vanlig klass och läsa in namnrymden Microsoft.AspNet.SignalR, och sedan ärva från Hub. Här i kan vi skriva de funktioner som vi vill exponera för klienterna, i mitt fall SkickaMeddelande.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;

namespace WebApplication3.App_Code
{
   public class MinTestHub : Hub
   {
      public void SkickaMeddelande(string meddelande)
      {
         this.Clients.All.servernPratar(
            "Ett meddelande: " + meddelande);
      }
   }
}

Visual Studios texteditor är inte speciellt hjälpsam eftersom koden är dynamisk och okänd för Visual Studio, men detta betyder att när en klient får för sig att anropa servern med SignalR, så svarar servern genom att anropa alla klienter.

Tänk på att hubben exponeras som ett attribut till ett JavaScript-objekt, connection, på klientsidan med första bokstaven som gemen, vilket betyder att denna hubb kommer att heta minTestHub på klienten – inte MinTestHub.

För att summera klassen MinTestHub: Funktionen SkickaMeddelande exponeras för klienterna och låter dem prata med servern. Servern svarar genom att anropa JavaScript-funktionen servernPratar hos alla klienterna.

Det som återstår nu är klientkoden. Jag skriver den i applikationens startsida, Views/Home/Index.cshtml.

På en lämplig plats vill jag ha en knapp kallad SendFromClient och därefter öppnar jag ett script-block.

<input type="button" id="SendFromClient" value="Send from client" />
<script type="text/javascript">

</script>

All kod skriver jag i jQuery:s uppstartevent. Det innebär att hela koden är inkapslad av $(function () { och });. I script-blocket gör jag två saker. Först ansluter jag mig till hubben och tillhandahåller definitionen av servernPratar, alltså skriver vad som ska hända när ett anrop från servern kommer in.

var testhub = $.connection.minTestHub;
testhub.client.servernPratar = function (meddelande) {
   alert(meddelande);
};

Därefter, när hubben är startad, så talar jag om vad som ska hända när knappen blir klickad på. Då vill jag anropa funktionen skickaMeddelande på servern.

$.connection.hub.start().done(function () {
   $("#SendFromClient").click(function () {
      testhub.server.skickaMeddelande("Hej från klienten!");
   });
});

Hela klientkoden som jag infogar ser alltså ut så här:

<input type="button" id="SendFromClient" value="Send from client" />

<script type="text/javascript">
   $(function () {

      var testhub = $.connection.minTestHub;
      testhub.client.servernPratar = function (meddelande) {
         alert(meddelande);
      };

      $.connection.hub.start().done(function () {
         $("#SendFromClient").click(function () {
            testhub.server.skickaMeddelande("Hej från klienten!");
         });
      });
   });
</script>

Om du testar att öppna flera webbläsare och surfar till din applikation, kommer du att se att när du klickar på knappen på en av dem, så visar sig meddelanderutan i alla. (För bäst effekt, använd olika webbläsare med tanke på att en meddelanderuta kan blockera andra meddelanderutor.)

Hubben i din server blir hårt belastad kan meddelanden skickas i okontrollerad ordning. Det beror på att anropen till klienten är asynkrona, men detta kan avhjälpas med async och await.

Categories: C#

Tags: SignalR

Leave a Reply

Your email address will not be published. Required fields are marked *



En kopp kaffe!

Bjud mig på en kopp kaffe (20:-) som tack för bra innehåll!

Bjud på en kopp kaffe!

Om...

Kontaktuppgifter, med mera, finns här.

Följ mig

Twitter Instagram
GitHub RSS

Public Service

Folkbildning om public service.

Hem   |   linktr.ee/hesselbom   |   winsoft.se   |   80tal.se   |   Filmtips