So I was following several tutorials here: https://learn.microsoft.com/en-us/azure/azure-signalr/signalr-quickstart-azure-functions-csharp and https://learn.microsoft.com/en-us/azure/azure-signalr/signalr-concept-serverless-development-config
My problem is that all the examples show a CRON operation or just an in scope console log broadcast. But what I want an UPDATE to a collection to trigger a broadcast?
In a Web App I could do something like this. And this worked FINE when testing with multiple clients.
[HttpPost]
public async Task<IActionResult> Insert([FromQuery] string firstName, string lastName)
{
await _repo.InsertNewPerson(firstName, lastName);
//This hub essentially has almost nothing set up except:
// endpoints.MapHub<ContactsHub>("/contacts"); setup in startup
await _hub.Clients.All.SendAsync("transfercontactdata", _repo.GetContacts());
return StatusCode(201);
}
However in an Azure Function with doing Microsoft's canned class of adding a 'Broadcast' [SignalRTrigger] I see this
public class SignalRTestHub : ServerlessHub
{
private IContactsRepo _repo = new ContactsRepo();
[FunctionName("negotiate")]
public SignalRConnectionInfo Negotiate([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req, [SignalRConnectionInfo(HubName = "SignalRTestHub")] SignalRConnectionInfo connectionInfo)
{
return connectionInfo;
}
//Brett: Do I need this arg more in other events to ensure this acts as a load balancer??? ... ran out of time, [SignalRConnectionInfo(HubName = "SignalRTestHub")] SignalRConnectionInfo connectionInfo
[FunctionName(nameof(OnConnected))]
public async Task OnConnected([SignalRTrigger] InvocationContext invocationContext, ILogger logger, [SignalRConnectionInfo(HubName = "SignalRTestHub")] SignalRConnectionInfo connectionInfo)
{
//await Clients.All.SendAsync(NewConnectionTarget, new NewConnection(invocationContext.ConnectionId));
logger.LogInformation($"{invocationContext.ConnectionId} has connected");
}
[FunctionName(nameof(Broadcast))]
public async Task Broadcast([SignalRTrigger] InvocationContext invocationContext, string message, ILogger logger)
{
//Broadcast on update the same as the get call on the other function
await Clients.All.SendAsync("getting data", await _repo.GetContacts());
logger.LogInformation($"{invocationContext.ConnectionId} broadcast {message}");
}
[FunctionName(nameof(OnDisconnected))]
public void OnDisconnected([SignalRTrigger] InvocationContext invocationContext)
{
}
}
Then I have another Function of HTTP triggers like this:
public static class SignalRTesting
{
private static IContactsRepo _repo = new ContactsRepo();
private static SignalRTestHub _hub = new SignalRTestHub();
private static SignalRConnectionInfo _info;
static SignalRTesting()
{
//Not sure how connect or need to
_info = _hub.Negotiate(null, null);
}
[FunctionName("GetData")]
public static async Task<IActionResult> GetData([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req, ILogger log) => new OkObjectResult(await _repo.GetContacts());
[FunctionName("UpdateData")]
public static async Task<IActionResult> UpdateData([HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req, ILogger log)
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
var data = JsonConvert.DeserializeObject<Contact>(requestBody);
await _repo.InsertNewPerson(data.FirstName, data.LastName);
await _hub.Broadcast() //I need a context from above I am guessing
return new NoContentResult();
}
}
So my question is how do you get an HTTP POST or PUT request to call the broadcast with the functions? It seems to me that a hub broadcast needs a connection so almost like there was a service side acting like a client but I'm not sure.