Выходная привязка Службы SignalR для службы "Функции Azure"

Выходная привязка SignalR используется для отправки одного или нескольких сообщений с помощью службы Azure SignalR. Сообщение можно транслировать следующим получателям:

  • всем подключенным клиентам;
  • Подключение клиентов в указанной группе
  • подключенным клиентам, которые прошли аутентификацию для определенного пользователя.

Выходная привязка также позволяет управлять группами, например добавление клиента или пользователя в группу, удаление клиента или пользователя из группы.

Сведения об установке и настройке см. в обзорной статье.

Пример

Широковещательная передача для всех клиентов

Функцию C# можно создать с помощью одного из следующих режимов C#:

  • Изолированная рабочая модель: скомпилированная функция C#, которая выполняется в рабочем процессе, изолированном от среды выполнения. Изолированный рабочий процесс необходим для поддержки функций C#, работающих в LTS и не LTS-версиях .NET и платформа .NET Framework.
  • Модель внутрипроцессного процесса: скомпилированная функция C#, которая выполняется в том же процессе, что и среда выполнения Функций.
  • Скрипт C#: используется в основном при создании функций C# в портал Azure.

В следующем примере показана функция, отправляющая сообщение для всех подключенных клиентов с помощью выходной привязки. newMessage — это имя метода, вызываемого для каждого клиента.

[Function(nameof(BroadcastToAll))]
[SignalROutput(HubName = "chat", ConnectionStringSetting = "SignalRConnection")]
public static SignalRMessageAction BroadcastToAll([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
{
    using var bodyReader = new StreamReader(req.Body);
    return new SignalRMessageAction("newMessage")
    {
        // broadcast to all the connected clients without specifying any connection, user or group.
        Arguments = new[] { bodyReader.ReadToEnd() },
    };
}

Данные привязки в файле function.json:

Пример файла function.json:

{
  "type": "signalR",
  "name": "signalROutput",
  "hubName": "hubName1",
  "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
  "direction": "out"
}
const { app, output } = require('@azure/functions');

const signalR = output.generic({
    type: 'signalR',
    name: 'signalR',
    hubName: 'hub',
    connectionStringSetting: 'AzureSignalRConnectionString',
});

// You can use any other trigger type instead.
app.http('broadcast', {
    methods: ['GET'],
    authLevel: 'anonymous',
    extraOutputs: [signalR],
    handler: (request, context) => {
        context.extraOutputs.set(signalR, {
            "target": "newMessage",
            "arguments": [request.body]
        });
    }
});

Скоро должны появиться полные примеры PowerShell.

Ниже приведен код Python.

def main(req: func.HttpRequest, signalROutput: func.Out[str]) -> func.HttpResponse:
    message = req.get_json()
    signalROutput.set(json.dumps({
        'target': 'newMessage',
        'arguments': [ message ]
    }))
@FunctionName("sendMessage")
@SignalROutput(name = "$return", HubName = "hubName1")
public SignalRMessage sendMessage(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Object> req) {

    SignalRMessage message = new SignalRMessage();
    message.target = "newMessage";
    message.arguments.add(req.getBody());
    return message;
}

Отправка пользователю

Сообщения можно отправлять только для подключений, которые прошли аутентификацию для пользователя. Для этого в сообщении SignalR нужно задать идентификатор пользователя.

[Function(nameof(SendToUser))]
[SignalROutput(HubName = "chat", ConnectionStringSetting = "SignalRConnection")]
public static SignalRMessageAction SendToUser([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
{
    using var bodyReader = new StreamReader(req.Body);
    return new SignalRMessageAction("newMessage")
    {
        Arguments = new[] { bodyReader.ReadToEnd() },
        UserId = "userToSend",
    };
}

Данные привязки в файле function.json:

Пример файла function.json:

{
  "type": "signalR",
  "name": "signalROutput",
  "hubName": "hubName1",
  "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
  "direction": "out"
}

Скоро должны появиться полные примеры PowerShell.

Ниже приведен код Python.

def main(req: func.HttpRequest, signalROutput: func.Out[str]) -> func.HttpResponse:
    message = req.get_json()
    signalROutput.set(json.dumps({
        #message will only be sent to this user ID
        'userId': 'userId1',
        'target': 'newMessage',
        'arguments': [ message ]
    }))
@FunctionName("sendMessage")
@SignalROutput(name = "$return", HubName = "hubName1")
public SignalRMessage sendMessage(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Object> req) {

    SignalRMessage message = new SignalRMessage();
    message.userId = "userId1";
    message.target = "newMessage";
    message.arguments.add(req.getBody());
    return message;
}
const { app, output } = require('@azure/functions');

const signalR = output.generic({
    type: 'signalR',
    name: 'signalR',
    hubName: 'hub',
    connectionStringSetting: 'AzureSignalRConnectionString',
});

app.http('sendToUser', {
    methods: ['GET'],
    authLevel: 'anonymous',
    extraOutputs: [signalR],
    handler: (request, context) => {
        context.extraOutputs.set(signalR, {
            "target": "newMessage",
            "arguments": [request.body],
            "userId": "userId1",
        });
    }
});

Оправка группе

Сообщение можно отправить только для подключений, которые добавлены в группу. Для этого в сообщении SignalR нужно задать имя группы.

[Function(nameof(SendToGroup))]
[SignalROutput(HubName = "chat", ConnectionStringSetting = "SignalRConnection")]
public static SignalRMessageAction SendToGroup([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
{
    using var bodyReader = new StreamReader(req.Body);
    return new SignalRMessageAction("newMessage")
    {
        Arguments = new[] { bodyReader.ReadToEnd() },
        GroupName = "groupToSend"
    };
}

Данные привязки в файле function.json:

Пример файла function.json:

{
  "type": "signalR",
  "name": "signalROutput",
  "hubName": "hubName1",
  "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
  "direction": "out"
}
const { app, output } = require('@azure/functions');

const signalR = output.generic({
    type: 'signalR',
    name: 'signalR',
    hubName: 'hub',
    connectionStringSetting: 'AzureSignalRConnectionString',
});

app.http('sendToGroup', {
    methods: ['GET'],
    authLevel: 'anonymous',
    extraOutputs: [signalR],
    handler: (request, context) => {
        context.extraOutputs.set(signalR, {
            "target": "newMessage",
            "arguments": [request.body],
            "groupName": "myGroup",
        });
    }
});

Скоро должны появиться полные примеры PowerShell.

Ниже приведен код Python.

def main(req: func.HttpRequest, signalROutput: func.Out[str]) -> func.HttpResponse:
    message = req.get_json()
    signalROutput.set(json.dumps({
        #message will only be sent to this group
        'groupName': 'myGroup',
        'target': 'newMessage',
        'arguments': [ message ]
    }))
@FunctionName("sendMessage")
@SignalROutput(name = "$return", HubName = "hubName1")
public SignalRMessage sendMessage(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Object> req) {

    SignalRMessage message = new SignalRMessage();
    message.groupName = "myGroup";
    message.target = "newMessage";
    message.arguments.add(req.getBody());
    return message;
}

Управление группами

Служба SignalR позволяет добавлять пользователей или подключения в группы. Затем сообщения можно отправлять группе. Выходную привязку SignalR можно использовать для управления группами.

Укажите SignalRGroupActionType для добавления или удаления участника. В примере ниже пользователь удаляется из группы.

[Function(nameof(RemoveFromGroup))]
[SignalROutput(HubName = "chat", ConnectionStringSetting = "SignalRConnection")]
public static SignalRGroupAction RemoveFromGroup([HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequestData req)
{
    return new SignalRGroupAction(SignalRGroupActionType.Remove)
    {
        GroupName = "group1",
        UserId = "user1"
    };
}

Примечание.

Чтобы получить правильную привязку ClaimsPrincipal, необходимо настроить параметры аутентификации в службе "Функции Azure".

Данные привязки в файле function.json:

Пример файла function.json:

{
  "type": "signalR",
  "name": "signalROutput",
  "hubName": "hubName1",
  "connectionStringSetting": "<name of setting containing SignalR Service connection string>",
  "direction": "out"
}
const { app, output } = require('@azure/functions');

const signalR = output.generic({
    type: 'signalR',
    name: 'signalR',
    hubName: 'hub',
    connectionStringSetting: 'AzureSignalRConnectionString',
});

// The following function adds a user to a group
app.http('addUserToGroup', {
    methods: ['POST'],
    authLevel: 'anonymous',
    extraOutputs: [signalR],
    handler: (request, context) => {
        context.extraOutputs.set(signalR, {
            "userId": req.query.userId,
            "groupName": "myGroup",
            "action": "add"
        });
    }
});

// The following function removes a user from a group
app.http('removeUserFromGroup', {
    methods: ['POST'],
    authLevel: 'anonymous',
    extraOutputs: [signalR],
    handler: (request, context) => {
        context.extraOutputs.set(signalR, {
            "userId": req.query.userId,
            "groupName": "myGroup",
            "action": "remove"
        });
    }
});

Скоро должны появиться полные примеры PowerShell.

В примере ниже пользователь добавляется в группу.

def main(req: func.HttpRequest, signalROutput: func.Out[str]) -> func.HttpResponse:
    signalROutput.set(json.dumps({
        'userId': 'userId1',
        'groupName': 'myGroup',
        'action': 'add'
    }))

В примере ниже пользователь удаляется из группы.

def main(req: func.HttpRequest, signalROutput: func.Out[str]) -> func.HttpResponse:
    signalROutput.set(json.dumps({
        'userId': 'userId1',
        'groupName': 'myGroup',
        'action': 'remove'
    }))

В примере ниже пользователь добавляется в группу.

@FunctionName("addToGroup")
@SignalROutput(name = "$return", HubName = "hubName1")
public SignalRGroupAction addToGroup(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Object> req,
        @BindingName("userId") String userId) {

    SignalRGroupAction groupAction = new SignalRGroupAction();
    groupAction.action = "add";
    groupAction.userId = userId;
    groupAction.groupName = "myGroup";
    return action;
}

В примере ниже пользователь удаляется из группы.

@FunctionName("removeFromGroup")
@SignalROutput(name = "$return", HubName = "hubName1")
public SignalRGroupAction removeFromGroup(
        @HttpTrigger(
            name = "req",
            methods = { HttpMethod.POST },
            authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Object> req,
        @BindingName("userId") String userId) {

    SignalRGroupAction groupAction = new SignalRGroupAction();
    groupAction.action = "remove";
    groupAction.userId = userId;
    groupAction.groupName = "myGroup";
    return action;
}

Атрибуты

Библиотеки C# в процессе и изолированном рабочем процессе используют атрибут для определения функции. Вместо этого в скрипте C# используется файл конфигурации function.json.

В следующей таблице описываются свойства атрибута SignalROutput.

Свойство атрибута Description
HubName В качестве значения следует указать имя центра SignalR, для которого создаются сведения о подключении.
ConnectionStringSetting Имя параметра приложения, который содержит строку подключения службы SignalR (по умолчанию используется AzureSignalRConnectionString).

Заметки

В следующей таблице описаны поддерживаемые параметры заметки SignalROutput.

Параметр Description
name Имя переменной, используемой в коде функции для объекта сведений о подключении.
hubName В качестве значения следует указать имя центра SignalR, для которого создаются сведения о подключении.
connectionStringSetting Имя параметра приложения, который содержит строку подключения службы SignalR (по умолчанию используется AzureSignalRConnectionString).

Настройка

В следующей таблице описываются свойства конфигурации привязки, которые задаются в файле function.json.

Свойство в function.json Описание
type Должен иметь значениеsignalR.
direction Должен иметь значениеout.
name Имя переменной, используемой в коде функции для объекта сведений о подключении.
hubName В качестве значения следует указать имя центра SignalR, для которого создаются сведения о подключении.
connectionStringSetting Имя параметра приложения, который содержит строку подключения службы SignalR (по умолчанию используется AzureSignalRConnectionString).

Если разработка ведется на локальном компьютере, добавьте параметры приложения в файл local.settings.json в коллекции Values.

Следующие шаги