Update the upstream URL pattern so that it contains the SignalR extension key:

The SignalR extension key can be found under App Keys:

Appendix:
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using static AzureSignalR.LocationReporting.Language;
namespace AzureSignalR.Functions
{
public class LocationHub : ServerlessHub
{
const string NewMessageTarget = "newMessage";
const string NewConnectionTarget = "newConnection";
[FunctionName("negotiate")]
public SignalRConnectionInfo Negotiate([HttpTrigger(AuthorizationLevel.Anonymous)] HttpRequest req)
{
return Negotiate(null, null, new System.TimeSpan(1,0,0));
}
[FunctionName(nameof(OnConnected))]
public async Task OnConnected([SignalRTrigger] InvocationContext invocationContext, ILogger logger)
{
invocationContext.Headers.TryGetValue("Authorization", out var auth);
await Clients.All.SendAsync(NewConnectionTarget, new NewConnection(invocationContext.ConnectionId, auth));
logger.LogInformation($"{invocationContext.ConnectionId} has connected");
}
[FunctionAuthorize]
[FunctionName(nameof(LocationUpdate))]
public async Task LocationUpdate([SignalRTrigger] InvocationContext invocationContext, SubjectLocation update, ILogger logger)
{
await Clients.All.SendAsync(NewMessageTarget, new NewMessage(invocationContext, update));
logger.LogInformation($"{invocationContext.ConnectionId} broadcast {update}");
}
[FunctionName(nameof(SendToGroup))]
public async Task SendToGroup([SignalRTrigger] InvocationContext invocationContext, string groupName, SubjectLocation msg)
{
await Clients.Group(groupName).SendAsync(NewMessageTarget, new NewMessage(invocationContext, msg));
}
[FunctionName(nameof(SendToUser))]
public async Task SendToUser([SignalRTrigger] InvocationContext invocationContext, string userName, SubjectLocation update)
{
await Clients.User(userName).SendAsync(NewMessageTarget, new NewMessage(invocationContext, update));
}
[FunctionName(nameof(SendToConnection))]
public async Task SendToConnection([SignalRTrigger] InvocationContext invocationContext, string connectionId, SubjectLocation update)
{
await Clients.Client(connectionId).SendAsync(NewMessageTarget, new NewMessage(invocationContext, update));
}
[FunctionName(nameof(JoinGroup))]
public async Task JoinGroup([SignalRTrigger] InvocationContext invocationContext, string groupName)
{
await Groups.AddToGroupAsync(invocationContext.ConnectionId, groupName);
}
[FunctionName(nameof(LeaveGroup))]
public async Task LeaveGroup([SignalRTrigger] InvocationContext invocationContext, string connectionId, string groupName)
{
await Groups.RemoveFromGroupAsync(connectionId, groupName);
}
[FunctionName(nameof(JoinUserToGroup))]
public async Task JoinUserToGroup([SignalRTrigger] InvocationContext invocationContext, string userName, string groupName)
{
await UserGroups.AddToGroupAsync(userName, groupName);
}
[FunctionName(nameof(LeaveUserFromGroup))]
public async Task LeaveUserFromGroup([SignalRTrigger] InvocationContext invocationContext, string userName, string groupName)
{
await UserGroups.RemoveFromGroupAsync(userName, groupName);
}
[FunctionName(nameof(OnDisconnected))]
public void OnDisconnected([SignalRTrigger] InvocationContext invocationContext)
{
}
class NewConnection
{
public string ConnectionId { get; }
public string Authentication { get; }
public NewConnection(string connectionId, string authentication)
{
ConnectionId = connectionId;
Authentication = authentication;
}
}
class NewMessage
{
public string ConnectionId { get; }
public string Sender { get; }
public SubjectLocation Update { get; }
public NewMessage(InvocationContext invocationContext, SubjectLocation update)
{
Sender = string.IsNullOrEmpty(invocationContext.UserId) ? string.Empty : invocationContext.UserId;
ConnectionId = invocationContext.ConnectionId;
Update = update;
}
}
}
}