Início Rápido: criar um aplicativo sem servidor com o Azure Functions e o Serviço do Azure SignalR em Python
Comece com o Serviço do Azure SignalR usando o Azure Functions e o Python para criar um aplicativo sem servidor que transmite mensagens para clientes. Você executará a função no ambiente local, conectando uma instância do Serviço do Azure SignalR na nuvem. A realização deste início rápido gera um pequeno custo de alguns centavos de dólar ou menos em sua Conta do Azure.
Observação
Você pode obter o código neste artigo do GitHub.
Pré-requisitos
Este início rápido pode ser executado no macOS, Windows ou Linux. Você precisará do seguinte:
Pré-requisito | Descrição |
---|---|
Uma assinatura do Azure | Se você não tem uma assinatura do Azure, crie uma conta gratuita do Azure |
Um editor de código | Você precisará de um editor de código como o Visual Studio Code. |
Azure Functions Core Tools | Exige a versão 2.7.1505 ou superior para executar aplicativos Python Azure Function localmente. |
Python 3.7+ | O Azure Functions exige o Python 3.7+. Confira Versões do Python com suporte . |
Azurite | A associação do SignalR precisa do Armazenamento do Azure. Você pode usar um emulador de armazenamento local quando uma função estiver sendo executada localmente. |
CLI do Azure | Opcionalmente, você pode usar a CLI do Azure para criar uma instância do Serviço do Azure SignalR. |
Criar uma instância do Serviço Azure SignalR
Nesta seção, você cria uma instância básica do Azure SignalR para usar em seu aplicativo. As etapas a seguir usam o portal do Azure para criar uma nova instância, mas você também pode usar a CLI do Azure. Para obter mais informações, consulte o comando az signalr create na referência da CLI do serviço do Azure SignalR.
- Entre no portal do Azure.
- No canto superior esquerdo da página, escolha + Criar um recurso.
- Na página Criar um recurso, na caixa de texto serviços Pesquisa e marketplace, insira signalr e, em seguida, selecione Serviço do SignalR na lista.
- Na página Serviço do SignalR, selecione Criar.
- Na guia Noções básicas, você insere as informações essenciais para a nova instância do Serviço do SignalR. Insira os valores a seguir:
Campo | Valor sugerido | Descrição |
---|---|---|
Assinatura | Escolha sua assinatura | Selecione a assinatura que você deseja usar para criar uma nova instância do serviço do SignalR. |
Grupo de recursos | Criar um grupo de recursos chamado SignalRTestResources | Selecione ou crie um grupo de recursos para seu recurso do SignalR. É útil criar um novo grupo de recursos para este tutorial em vez de usar um grupo de recursos existente. Para liberar recursos depois de concluir o tutorial, exclua o grupo de recursos. A exclusão de um grupo de recursos também exclui todos os recursos que pertencem ao grupo. Essa ação não pode ser desfeita. Antes de excluir um grupo de recursos, certifique-se de que ele não contenha os recursos que você deseja manter. Para obter mais informações, consulte Usando os grupos de recursos para gerenciar seus recursos do Azure. |
Nome do recurso | testsignalr | Insira um nome exclusivo do recurso a ser usado para o recurso do SignalR. Se testsignalr já estiver sendo usado em sua região, adicione um dígito ou caractere até que o nome seja exclusivo. O nome deve ser uma cadeia de caracteres com 1 a 63 caracteres, e deve conter somente números, letras e o hífen ( - ). O nome não pode começar nem terminar com o caractere hífen, e os caracteres hífen consecutivos não serão válidos. |
Região | Escolha a região | Selecione a região apropriada para sua nova instância do serviço do SignalR. O serviço do Azure SignalR não está disponível atualmente em todas as regiões. Para saber mais, confira Disponibilidade por região do serviço do Azure SignalR |
Tipo de preços | Selecione Alterar e, em seguida, escolha Gratuito (somente desenvolvimento/teste). Escolha Selecionar para confirmar sua escolha de tipo de preço. | O serviço do Azure SignalR tem três tipos de preço: Gratuito, Standard e Premium. Os tutoriais usam o tipo Gratuito, a menos que indicado de outra forma nos pré-requisitos. Para obter mais informações sobre as diferenças de funcionalidade entre tipos e preços, consulte preço do serviço do Azure SignalR |
Modo de serviço | Escolha o modo de serviço apropriado | Use Padrão quando hospedar a lógica do hub do SignalR em seus aplicativos Web e usar o serviço SignalR como um proxy. Use Sem servidor quando usar tecnologias sem servidor, como o Azure Functions, para hospedar a lógica do hub do SignalR. O modo Clássico é apenas para compatibilidade com versões anteriores e não é recomendável usar. Para obter mais informações, confira Modo de serviço no serviço do Azure SignalR. |
Você não precisa alterar as configurações nas guias Rede e Marcações para os tutoriais do SignalR.
- Selecione o botão Revisar + criar na parte inferior da guia Noções básicas.
- Na guia Revisar + Criar, revise os valores e, em seguida, selecione Criar. A implantação leva alguns momentos para ser concluída.
- Depois que a implantação estiver concluída, selecione o botão Ir para o recurso.
- Na tela de recursos do SignalR, selecione Chaves no menu à esquerda, em Configurações.
- Copie a Cadeia de conexão para a chave primária. Você precisa dessa cadeia de conexão para configurar seu aplicativo posteriormente neste tutorial.
Criar um projeto do Azure Function
Criar um projeto local do Azure Function.
- A partir de uma linha de comando, crie um diretório para seu projeto.
- Altere para o diretório do projeto.
- Use o comando
func init
do Azure Functions para inicializar seu projeto de função.
# Initialize a function project
func init --worker-runtime python
Criar as funções
Depois de inicializar um projeto, você precisa criar funções. Esse projeto requer três funções:
index
: hospeda uma página web para um cliente.negotiate
: permite que um cliente obtenha um token de acesso.broadcast
: usa um gatilho de tempo para transmitir mensagens periodicamente a todos os clientes.
Quando você executa o comando func new
no diretório raiz do projeto, o Azure Functions Core Tools acrescenta o código de função no arquivofunction_app.py
. Você editará o conteúdo do anúncio de parâmetros conforme necessário, substituindo o código padrão pelo código do aplicativo.
Cria a função do índice
Você pode usar essa função de exemplo como um modelo para suas próprias funções.
Abra o arquivo function_app.py
. Esse arquivo conterá suas funções. Primeiro, modifique o arquivo para incluir as instruções de importação necessárias e defina variáveis globais que usaremos nas funções a seguir.
import azure.functions as func
import os
import requests
import json
app = func.FunctionApp()
etag = ''
start_count = 0
- Adicione a função
index
adicionando o código a seguir
@app.route(route="index", auth_level=func.AuthLevel.ANONYMOUS)
def index(req: func.HttpRequest) -> func.HttpResponse:
f = open(os.path.dirname(os.path.realpath(__file__)) + '/content/index.html')
return func.HttpResponse(f.read(), mimetype='text/html')
Essa função hospeda uma página da Web para um cliente.
Criar a função negociar
Adicione a função negotiate
adicionando o código a seguir
@app.route(route="negotiate", auth_level=func.AuthLevel.ANONYMOUS, methods=["POST"])
@app.generic_input_binding(arg_name="connectionInfo", type="signalRConnectionInfo", hubName="serverless", connectionStringSetting="AzureSignalRConnectionString")
def negotiate(req: func.HttpRequest, connectionInfo) -> func.HttpResponse:
return func.HttpResponse(connectionInfo)
Essa função permite que um cliente obtenha um token de acesso.
Criar uma função de transmissão.
Adicione a função broadcast
adicionando o código a seguir
@app.timer_trigger(schedule="*/1 * * * *", arg_name="myTimer",
run_on_startup=False,
use_monitor=False)
@app.generic_output_binding(arg_name="signalRMessages", type="signalR", hubName="serverless", connectionStringSetting="AzureSignalRConnectionString")
def broadcast(myTimer: func.TimerRequest, signalRMessages: func.Out[str]) -> None:
global etag
global start_count
headers = {'User-Agent': 'serverless', 'If-None-Match': etag}
res = requests.get('https://api.github.com/repos/azure/azure-functions-python-worker', headers=headers)
if res.headers.get('ETag'):
etag = res.headers.get('ETag')
if res.status_code == 200:
jres = res.json()
start_count = jres['stargazers_count']
signalRMessages.set(json.dumps({
'target': 'newMessage',
'arguments': [ 'Current star count of https://api.github.com/repos/azure/azure-functions-python-worker is: ' + str(start_count) ]
}))
Essa função usa um gatilho de tempo para transmitir mensagens periodicamente para todos os clientes.
Criar um projeto do Azure Function
Criar um projeto local do Azure Function.
- A partir de uma linha de comando, crie um diretório para seu projeto.
- Altere para o diretório do projeto.
- Use o comando
func init
do Azure Functions para inicializar seu projeto de função.
# Initialize a function project
func init --worker-runtime python --model v1
Criar as funções
Depois de inicializar um projeto, você precisa criar funções. Esse projeto requer três funções:
index
: hospeda uma página web para um cliente.negotiate
: permite que um cliente obtenha um token de acesso.broadcast
: usa um gatilho de tempo para transmitir mensagens periodicamente a todos os clientes.
Quando você executa o comando func new
no diretório raiz do projeto, o Azure Functions Core Tools cria arquivos de origem de função padrão e os armazena em uma pasta com o nome da função. Você editará os arquivos conforme necessário, substituindo o código padrão pelo código do aplicativo.
Cria a função do índice
Você pode usar essa função de exemplo como um modelo para suas próprias funções.
- Execute o seguinte comando para criar a função
index
.
func new -n index -t HttpTrigger
- Edite index/function.json e substitua o conteúdo pelo código json a seguir:
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "$return"
}
]
}
- Edite index/_init_.py e substitua o conteúdo pelo código a seguir:
import os
import azure.functions as func
def main(req: func.HttpRequest) -> func.HttpResponse:
f = open(os.path.dirname(os.path.realpath(__file__)) + '/../content/index.html')
return func.HttpResponse(f.read(), mimetype='text/html')
Criar a função negociar
- Execute o comando a seguir para criar a função
negotiate
.
func new -n negotiate -t HttpTrigger
- Edite negotiate/function.json e substitua o conteúdo pelo código json a seguir:
{
"scriptFile": "__init__.py",
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "$return"
},
{
"type": "signalRConnectionInfo",
"name": "connectionInfo",
"hubName": "serverless",
"connectionStringSetting": "AzureSignalRConnectionString",
"direction": "in"
}
]
}
- Edite negotiate/_init_.py e substitua o conteúdo pelo código a seguir:
import azure.functions as func
def main(req: func.HttpRequest, connectionInfo) -> func.HttpResponse:
return func.HttpResponse(connectionInfo)
Criar uma função de transmissão.
- Execute o comando a seguir para criar a função de
broadcast
.
func new -n broadcast -t TimerTrigger
# install requests
pip install requests
- Edite broadcast/function.json e substitua o conteúdo pelo seguinte código:
{
"scriptFile": "__init__.py",
"bindings": [
{
"name": "myTimer",
"type": "timerTrigger",
"direction": "in",
"schedule": "*/5 * * * * *"
},
{
"type": "signalR",
"name": "signalRMessages",
"hubName": "serverless",
"connectionStringSetting": "AzureSignalRConnectionString",
"direction": "out"
}
]
}
- Edite broadcast/_init_.py e substitua o conteúdo pelo código a seguir:
import requests
import json
import azure.functions as func
etag = ''
start_count = 0
def main(myTimer: func.TimerRequest, signalRMessages: func.Out[str]) -> None:
global etag
global start_count
headers = {'User-Agent': 'serverless', 'If-None-Match': etag}
res = requests.get('https://api.github.com/repos/azure/azure-signalr', headers=headers)
if res.headers.get('ETag'):
etag = res.headers.get('ETag')
if res.status_code == 200:
jres = res.json()
start_count = jres['stargazers_count']
signalRMessages.set(json.dumps({
'target': 'newMessage',
'arguments': [ 'Current star count of https://github.com/Azure/azure-signalr is: ' + str(start_count) ]
}))
Criar o arquivo index.html
A interface do cliente para esse aplicativo é uma página web. A função index
lê o conteúdo HTML do arquivo content/index.html.
- Crie uma pasta chamada
content
na pasta raiz do seu projeto. - Crie o arquivo content/index.html.
- Copie o conteúdo a seguir para o arquivo content/index.html e salve-o:
<html>
<body>
<h1>Azure SignalR Serverless Sample</h1>
<div id="messages"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/3.1.7/signalr.min.js"></script>
<script>
let messages = document.querySelector('#messages');
const apiBaseUrl = window.location.origin;
const connection = new signalR.HubConnectionBuilder()
.withUrl(apiBaseUrl + '/api')
.configureLogging(signalR.LogLevel.Information)
.build();
connection.on('newMessage', (message) => {
document.getElementById("messages").innerHTML = message;
});
connection.start()
.catch(console.error);
</script>
</body>
</html>
Adicionar a cadeia de conexão de Serviço do Azure SignalR às configurações do aplicativo de função
A última etapa é definir a cadeia de conexão do Serviço do SignalR nas configurações do aplicativo Azure Function.
No portal do Azure, acesse a instância do SignalR que você implantou anteriormente.
Selecione Chaves para exibir as cadeias de conexão para a instância do SignalR Service.
Copie a cadeia de conexão primária e execute o comando:
func settings add AzureSignalRConnectionString "<signalr-connection-string>"
Execute o aplicativo do Azure Functions localmente
Inicie o emulador de armazenamento do Azurite:
azurite
Execute o aplicativo do Azure Functions no ambiente local:
func start
Observação
Se estiver vendo erros que mostram erros de leitura no armazenamento de blobs, certifique-se de que a configuração "AzureWebJobsStorage" no arquivo local.settings.json esteja definida como UseDevelopmentStorage=true
.
Depois que o Azure Function estiver sendo executado localmente, vá para http://localhost:7071/api/index
. A página exibe o número atual de estrelas para o repositório do Azure/azure-signalr no GitHub. Ao adicionar ou remover uma estrela do repositório no GitHub, você verá a contagem atualizada a cada poucos segundos.
Limpar os recursos
Se você não pretende continuar a usar este aplicativo, exclua todos os recursos criados por esse início rápido com as seguintes etapas para não incorrer em alterações:
No portal do Azure, selecione Grupos de recursos na extremidade esquerda, depois selecione o recurso de grupo que você criou. Como alternativa, você pode usar a caixa de pesquisa para localizar o grupo de recursos pelo nome.
Na janela que se abre, selecione o grupo de recursos e clique em Excluir grupo de recursos.
Na nova janela, digite o nome do grupo de recursos a ser excluído, depois clique em Excluir.
Está com problemas? Experimente o guia de solução de problemas ou fale conosco.
Próximas etapas
Neste início rápido, você criou e executou um aplicativo sem servidor em tempo real no local. Em seguida, saiba mais sobre como usar a comunicação bidirecional entre os clientes e o Azure Function com o Serviço do SignalR.