简体   繁体   中英

SignalR Azure function with input binding returning value

An azure function with signalR input binding can get some parameters. For example

 [FunctionName("SignalRTest")]
    public async Task SendMessage([SignalRTrigger]InvocationContext invocationContext, string message, ILogger logger)
    {
        logger.LogInformation($"Receive {message} from {invocationContext.ConnectionId}.");
    }

In the function it can invoke the clients eg

[FunctionName("SendMessage")]
public static Task SendMessage(
    [HttpTrigger(AuthorizationLevel.Anonymous, "post")]object message, 
    [SignalR(HubName = "chat")]IAsyncCollector<SignalRMessage> signalRMessages)
{
    return signalRMessages.AddAsync(
        new SignalRMessage 
        {
            // the message will only be sent to this user ID
            UserId = "userId1",
            Target = "newMessage",
            Arguments = new [] { message }
        });
}

But is it possible for the azure function with input binding to return something ?

I'd like to have

 [FunctionName("SignalRTest")]
    public async Task<string> SendMessage([SignalRTrigger]InvocationContext invocationContext, string message, ILogger logger)
    {
        return "123";
    }

and

id = connection.invoke("SendMessage", "test");

but it does not seem to work.

Thank you.

My team set it up so that a hub operation actually "returns" twice, and maybe this is what you're looking for.

When a hub operation is invoked, we have synchronous code do whatever it needs to do and return a result object, which is usually a model from a backend service we're calling. That is pushed to the client via client.SendAsync where client is IClientProxy . That's going to ultimately invoke a JS handler on your front end.

However, should something break, we may not get that callback to the JS handler. In that case, we also have our hub operations return a Task<IActionResult> that the front JS can handle. That acts more like a HTTP status code response.

In the end, each hub operation we invoke has at least 1 response, which is the IActionResult:

{"type":3,"invocationId":"0","result":{"statusCode":200}}

This approach allows us to setup a reusable client that behaves more like a normal REST client in that we can use the IActionResult response to trigger exception handling.

Example:

try
    {
      const result = await this.connection.invoke(callSettings.operation, callSettings.args);

      if (responseHandler){
        const apiResponse = new ApiResponse({ statusCode: result.statusCode });
        responseHandler.handleStatusCode(apiResponse, callSettings.operation, callSettings.args);
      }

      hubResponse.success = result.statusCode < 300;
      hubResponse.httpStatusCode = result.statusCode;
      hubResponse.body = result;
    }
    catch (err)
    {
      hubResponse.success = false;
      this.loggerService.logException(err, callSettings.operation);
      throw(err);
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM