I have a function that is used to store data. This data is monitored in a frontend and when there is new data, I want to notify my frontend about that.
I have achieved that by using SignalR, which to work requires me to return SignalRMessageAction from my function instead of typical HttpResponseData.
This is functioning, however there are some problems and questions that I have.
-
I have error-handling middleware that is configured to catch all of my custom exception, however when I throw an exception from a function that returns SignalRMessageAction, it is not caught and my server return 500 instead of meaningful exception.
-
Imagine that I want to have GET request that when triggered, will also notify subscribers and will return requested data and not the SignalRMessageAction.
Here is simplified example how I use it now.
[Function("StoreGeofenceMessage")]
[SignalROutput(HubName = "myhub")] //Hub name is not actually used anywhere
public async Task<SignalRMessageAction> RunStoreMessage(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "v1/messages")] HttpRequestData req,
FunctionContext executionContext)
{
var requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
MessageType messageType = data.type;;
int geofenceId = data.geofenceId;
DateTime timestamp = data.timestamp;
var geofenceMessage = new GeofenceMessage(geofenceId, timestamp, messageType);
messagesService.StoreMessage(geofenceMessage);
return new SignalRMessageAction("dashboardUpdate")
{
Arguments = new object[] { }
};
}
This is the Negotiate function
[Function("Negotiate")]
public SignalRConnectionInfo Negotiate(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "v1/negotiate")]
HttpRequestData req,
[SignalRConnectionInfoInput(HubName = "myhub")]
SignalRConnectionInfo connectionInfo)
{
return connectionInfo;
}
I have tried to search for more information, but couldn’t find something useful.
I expect that I will have control over the response from my server and will be able to notify my subscribers in some other form.
2
Answers
I have managed to solve my problem with a little bit more elegant solution that the one provided by Sampath (which I think that also should work).
I have used ServiceHubContext to send messages instead of the output binding, so I have made this service:
and then just inject that service like:
Credits to hannes neukermans in this post.
To achieve returning
HttpResponseData
instead ofSignalRMessageAction
from your Azure Functions Isolated while still notifying subscribers through SignalR, you can follow these steps:Separate SignalR Invocation and HTTP Response:
SignalRMessageAction
, you can notify subscribers through SignalR and then return an appropriate HTTP response.Handle SignalR Invocation:
Return HttpResponseData:
The sample code below uses HttpResponseData.
Code: