Search code examples
c#azuresignalrsignalr-hubazure-signalr

Not able to connect to Azure SignalR Hub


I could not connect to my Azure signalr service. I've created both app service (web app) and also signalr service. Once after that i deployed my server app into web app. Nevertheless when trying to connect from front end app i am getting forbidden 403 for unknown reason. Any thoughts?

From the client side perspective to which url should client be connected to? To the azure webapp or azure signalr service? Both got urls and signalr additionally got connection string + access key. From my understanding webapp connect to azure signalr by connection string and the clients should use web app url. Not sure.

Error:

Response status code does not indicate success: 403 (Forbidden).

server app (program.cs):

var builder = WebApplication.CreateBuilder(args);
//signalr azure service url
builder.Services.AddSignalR().AddAzureSignalR("Endpoint=https://signalrchatest.service.signalr.net;AccessKey=xxxx;");
var app = builder.Build();

app.UseDefaultFiles();
app.UseRouting();
app.UseStaticFiles();
app.MapHub<ChatHub>("/chathub");
app.Run();

fronend app:

_hubConnection = new HubConnectionBuilder()
            .WithUrl($"https://signalrchatest.service.signalr.net/chathub")
            .Build();

private async void ConnectToHub()
    {
        try
        {
            await _hubConnection.StartAsync();
        }
        catch (Exception ex)
            Console.WriteLine($"{ex.Message}");
    }

Solution

  • The 403 Forbidden error means that the server understands your request but refuses to authorize it. Refer to this link to resolve this error.

    Below is the complete setup and code for connecting your front-end and back-end to Azure SignalR Service:

    Program.cs (Server-side Code)

    using Microsoft.AspNetCore.SignalR;
    
    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddSignalR().AddAzureSignalR(options =>
    {
        options.ConnectionString = "<Your_SignalR_Connection_String>";
    });
    
    var app = builder.Build();
    
    app.UseDefaultFiles();
    app.UseRouting();
    app.UseStaticFiles();
    app.MapHub<ChatHub>("/chathub");
    app.Run();
    

    Create a ChatHub class that clients will interact with:.

    using Microsoft.AspNetCore.SignalR;
    
    public class ChatHub : Hub
    {
        public Task SendMessage(string user, string message)
        {
            return Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
    

    In the ConfigureServices method, configure CORS policies:

    var allowedSpecificOriginsPolicy = "_AllowedSpecificOriginsPolicy";
    builder.Services.AddCors(options =>
    {
        options.AddPolicy(allowedSpecificOriginsPolicy, builder =>
        {
            builder.WithOrigins("http://localhost:5001")
                .AllowAnyHeader()
                .AllowAnyMethod()
                .AllowCredentials();
        });
    });
    app.UseCors(allowedSpecificOriginsPolicy);
    

    Refer to this guide to use Azure SignalR Service.

    Client-Side :

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>SignalR Chat</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/6.0.1/signalr.js"></script>
    </head>
    <body>
        <h2>Azure SignalR Chat</h2>
        <input type="text" id="user" placeholder="Enter your name">
        <textarea id="message" placeholder="Type your message here"></textarea>
        <button id="sendMessage">Send Message</button>
    
        <div id="messages"></div>
    
        <script>
            var connection = new signalR.HubConnectionBuilder()
                .withUrl("http://localhost:5001/chathub") 
                .build();
    document.getElementById("sendMessage").addEventListener("click", function () {
                var user = document.getElementById("user").value;
                var message = document.getElementById("message").value;
                connection.invoke("SendMessage", user, message)
                    .catch(function (err) {
                        return console.error(err.toString());
                    });
            });
            connection.on("ReceiveMessage", function (user, message) {
                var msg = user + ": " + message;
                var msgDiv = document.createElement("div");
                msgDiv.textContent = msg;
                document.getElementById("messages").appendChild(msgDiv);
            });
            connection.start()
                .then(function () {
                    console.log("Connected to SignalR Hub!");
                })
                .catch(function (err) {
                    console.error("Error starting connection: " + err.toString());
                });
        </script>
    </body>
    </html>
    
    

    Output

    For more details, refer to this guide for using the front-end and back-end with Azure signalR.