Intégration de SignalR avec .NET Core 3.1 et un client Vue.js

1.1 Création du projet .NET Core 3.1

Créez un nouveau projet ASP.NET Core 3.1 via la commande dotnet new mvc -n MonProjetSignalR ou via Visual Studio.

1.2 Ajout des packages NuGet

Ajoutez la référence Microsoft.AspNetCore.SignalR via NuGet Package Manager ou en modifiant le fichier .csproj :

<PackageReference Include="Microsoft.AspNetCore.SignalR" Version="1.1.0" />

1.3 Fichier de modèle : ChatMessageInfo

Créez une classe représentant un message dans le dossier Models :

namespace MonProjetSignalR.Models
{
    public class ChatMessageInfo
    {
        public string NomUtilisateur { get; set; }
        public string ContenuMessage { get; set; }
    }
}

1.4 Hub SignalR : ChatHub

Ajoutez un dossier Hubs et créez la classe ChatHub héritant de Hub :

using Microsoft.AspNetCore.SignalR;
using MonProjetSignalR.Models;
using System.Threading.Tasks;

namespace MonProjetSignalR.Hubs
{
    public class ChatHub : Hub
    {
        public override async Task OnConnectedAsync()
        {
            string identifiantConnexion = Context.ConnectionId;
            await base.OnConnectedAsync();
        }

        public async Task EnvoyerMessage(ChatMessageInfo donnees)
        {
            await Clients.All.SendAsync("RecevoirMessage", donnees);
        }

        public async Task EnvoyerMessageAuteur(string message)
        {
            await Clients.Caller.SendAsync("RecevoirMessage", message);
        }

        public async Task EnvoyerMessageGroupe(string message)
        {
            await Clients.Group("UtilisateursSignalR").SendAsync("RecevoirMessage", message);
        }
    }
}

1.5 Vue Razor : Index.cshtml

Moidfiez le fichier Views/Home/Index.cshtml :

@{
    ViewData["Title"] = "Démonstration SignalR";
}
<div class="text-center">
    <ul id="listeMessages" style="margin-bottom:20px"></ul>
    <form>
        <div class="form-group">
            <label for="nom">Utilisateur :</label>
            <input type="text" id="nom" name="nom" class="form-control" />
        </div>
        <div class="form-group">
            <label for="message">Message :</label>
            <textarea rows="5" cols="20" id="message" name="message" class="form-control"></textarea>
        </div>
        <input type="button" onclick="envoyerMessage()" value="Envoyer" />
    </form>
</div>

<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/signalr/dist/browser/signalr.min.js"></script>
<script>
    const connexion = new signalR.HubConnectionBuilder()
        .withUrl("/chathub")
        .configureLogging(signalR.LogLevel.Information)
        .build();

    async function demarrerConnexion() {
        try {
            await connexion.start();
            console.log("Connexion établie");
        } catch (err) {
            console.log(err);
            setTimeout(demarrerConnexion, 5000);
        }
    }

    demarrerConnexion();

    connexion.onclose(async () => {
        demarrerConnexion();
    });

    connexion.on("RecevoirMessage", function (donnees) {
        var li = document.createElement("li");
        li.innerText = donnees.nomUtilisateur + " : " + donnees.contenuMessage;
        document.getElementById("listeMessages").appendChild(li);
    });

    function envoyerMessage() {
        var utilisateur = $.trim($("#nom").val());
        var message = $.trim($("#message").val());
        connexion.invoke("EnvoyerMessage", { nomUtilisateur: utilisateur, contenuMessage: message })
            .catch(function (err) {
                console.error("Échec d'envoi : " + err.toString());
            });
    }
</script>

1.6 Configuration dans Startup.cs

Mettez à jour la classe Startup :

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

namespace MonProjetSignalR
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddCors(options =>
            {
                options.AddPolicy("PolitiqueCors",
                    builder => builder.AllowAnyMethod().AllowAnyHeader()
                                      .WithOrigins("http://localhost:5000")
                                      .AllowCredentials());
            });
            services.AddSignalR();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();
            app.UseCors("PolitiqueCors");
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapHub<ChatHub>("/chathub");
                endpoints.MapControllerRoute(
                    name: "default",
                    pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
    }
}

1.7 Structure du projet

Assurez-vous que l'arborescence inclut :

  • Models/ChatMessageInfo.cs
  • Hubs/ChatHub.cs
  • Views/Home/Index.cshtml
  • Startup.cs

1.8 Exécution

Lancez le projet avec dotnet run et accédez à http://localhost:5000. Placez un point d'arrêt pour vérifier le fonctionnement.

2.1 Création du projet Vue

Utilisez Vue CLI pour créer un nouveau projet :

vue create client-signalr
cd client-signalr

2.2 Installation du package SignalR

npm install @microsoft/signalr

Note : @aspnet/signalr est obsolète, utilisez @microsoft/signalr.

2.3 Composant Vue : Home.vue

Remplacez le contenu de src/components/HelloWorld.vue (ou créez Home.vue) :

<template>
  <div class="home">
    <h1>Démonstration SignalR avec Vue</h1>
    <input v-model="utilisateur" placeholder="Nom d'utilisateur" />
    <input v-model="message" placeholder="Message" />
    <button @click="envoyerATous">Envoyer à tous</button>
    <button @click="envoyerAMoi">Envoyer à moi-même</button>
    <div>
      <ul>
        <li v-for="(msg, index) in messages" :key="index">
          {{ msg.user }} dit : {{ msg.text }}
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import * as signalR from "@microsoft/signalr";

export default {
  name: 'SignalRDemo',
  data() {
    return {
      utilisateur: "",
      message: "",
      connexion: null,
      messages: []
    }
  },
  methods: {
    envoyerATous() {
      const donnees = {
        nomUtilisateur: this.utilisateur,
        contenuMessage: this.message
      };
      this.connexion.invoke("EnvoyerMessage", donnees)
        .catch(err => console.error(err));
    },
    envoyerAMoi() {
      this.connexion.invoke("EnvoyerMessageAuteur", this.message)
        .catch(err => console.error(err));
    }
  },
  created() {
    const self = this;
    this.connexion = new signalR.HubConnectionBuilder()
      .withUrl("http://localhost:5000/chathub", {
        skipNegotiation: true,
        transport: signalR.HttpTransportType.WebSockets
      })
      .configureLogging(signalR.LogLevel.Information)
      .build();
    this.connexion.on("RecevoirMessage", function(user, message) {
      self.messages.push({ user, text: message });
    });
    this.connexion.start().catch(err => console.log(err));
  }
}
</script>

<style scoped>
  h1 { font-weight: normal; }
  ul { list-style-type: none; padding: 0; }
  li { display: inline-block; margin: 0 10px; }
</style>

2.4 Ajustement du projet MVC

Pour éviter des conflits, commentez le contenu de Views/Home/Index.cshtml pendant les tests avec Vue.

2.5 Lancement du client Vue

npm run serve

Accédez à l'URL indiquée (généralement http://localhost:8080).

Étiquettes: SignalR .NET Core 3.1 Vue.js Hub WebSocket

Publié le 6 juin à 18h14