Crie um app de videoconferência com Twilio Programmable Video e as plataformas Angular e ASP.NET Core 3.0
Tempo de leitura: 15 minutos
A interação do usuário em tempo real é uma ótima maneira de aprimorar os recursos de comunicação e colaboração de um aplicativo da Web. O chat por vídeo é uma escolha óbvia para sites de vendas, suporte ao cliente e educação. Mas é prático de implementar? Se você estiver desenvolvendo com o Angular no front-end e o ASP.NET Core para o seu servidor, o Twilio Programmable Video permitirá que você adicione um chat por vídeo robusto ao seu aplicativo com eficácia.
Este post mostra como criar um aplicativo de chat por vídeo em execução usando o SDK do JavaScript da Twilio no SPA (single page application, aplicativo de página única) do Angular e o SDK do C# e .NET da Twilio no código do servidor ASP.NET Core. Você desenvolverá as interações necessárias para criação e participação em salas de chat por vídeo e para publicação e inscrição em faixas de áudio e vídeo dos participantes.
Para ver uma integração completa das APIs da Twilio em um aplicativo .NET Core, confira esta série de vídeos em cinco partes gratuita. Ela é separada deste tutorial, mas oferece uma lista completa de muitas APIs de uma só vez.
Criar um app de chat por vídeo com as plataformas ASP.NET Core 3.1, Angular 9 e Twilio(conteúdo em inglês)
Este post fornece instruções e código para a criação de um app de chat por vídeo com o ASP.NET Core 3.0. Para saber como criar o mesmo app com o ASP.NET Core 2.2, consulte o post: Criar um app de chat por vídeo com as plataformas ASP.NET Core 2.2, Angular e Twilio.
Pré-requisitos
Para criar o projeto de chat por vídeo descrito neste post, serão necessárias as seguintes tecnologias e ferramentas:
- SDK do .NET Core 3.0 (versão 3.0.100 ou posterior)
- npm e Node.js (versão 10.10.0 ou posterior)
- CLI do Angular (versão 8.2.14 ou posterior)
- Visual Studio Code, Visual Studio 2019 ou outro IDE compatível com os itens acima
- Git, se você for clonar o repositório complementar
Para obter o máximo deste post, é importante conhecer:
- Angular, incluindo Observables (observáveis) e Promises (promessas)
- ASP.NET Core, incluindo injeção de dependência
- C# 8
- TypeScript
O código-fonte deste projeto está disponível no GitHub. O código para ASP.NET Core 3.0 é fornecido no branch master. O código para ASP.NET Core 2.2 também pode ser encontrado no mesmo repositório do branch net2.2.
Começar a usar o Twilio Programmable Video
Para criar esse projeto com o SDK de vídeo da Twilio, será necessária uma conta de avaliação da Twilio gratuita e um projeto do Twilio Programmable Video. A configuração levará apenas alguns minutos.
Assim que você tiver uma conta da Twilio, acesse o console da Twilio e siga estas etapas:
- Na página inicial do dashboard, localize o Account SID (SID da conta) e o Auth Token (token de autenticação) e copie-os em um local seguro.
- Selecione a seção Programmable Video do console.
- Em Tools (Ferramentas) > API Keys (Chaves de API), crie uma nova chave de API com um nome amigável de sua escolha e copie o SID e o API Secret (segredo de API) em um local seguro.
As credenciais recém adquiridas são segredos de usuário, por isso é melhor não armazená-las no código-fonte do projeto. Uma maneira de mantê-las seguras e torná-las acessíveis na configuração do projeto é armazená-las como variáveis de ambiente na máquina de desenvolvimento.
ASP.NET Core pode acessar variáveis de ambiente por meio do pacote Microsoft.Extensions.Configuration
para que possam ser usadas como propriedades de um objeto IConfiguration
na classe Startup
. Nas instruções a seguir, veja como fazer isso no Windows.
Execute os comandos abaixo em um prompt de comando do Windows, substituindo suas credenciais pelos espaços reservados. Em outros sistemas operacionais, use comandos compatíveis para criar as mesmas variáveis de ambiente.
Caso você prefira, ou se o seu ambiente de desenvolvimento exigir, é possível colocar esses valores no arquivo appsettings.development.json, conforme indicado. Cuidado para não expor esse arquivo em um repositório de código-fonte ou em outro local de fácil acesso.
Criar o aplicativo ASP.NET Core
Com o modelo Angular e o NET Core 3.0, crie um aplicativo da Web ASP.NET chamado "VideoChat", usando a interface do usuário do Visual Studio 2019 ou a linha de comando dotnet
a seguir:
Este comando criará uma solução Visual Studio contendo um projeto ASP.NET Core configurado para usar um aplicativo Angular, ClientApp, como front-end. O código do lado do servidor é escrito em C# e tem duas finalidades principais: em primeiro lugar, ele serve o aplicativo da Web Angular, o layout HTML, o CSS e o código JavaScript. Em segundo lugar, ele funciona como uma API da Web. O aplicativo do lado do cliente tem a lógica para apresentar como as salas de chat por vídeo são criadas e acessadas, além de hospedar a transmissão de vídeo do participante para chats por vídeo ao vivo.
Adicionar o SDK da Twilio para C# e .NET
O aplicativo de servidor ASP.NET Core usará o SDK da Twilio para C# e .NET. Instale-o com o gerenciador de pacotes NuGet, o console do gerenciador de pacotes ou com a seguinte instrução de linha de comando dotnet
:
Ao concluir o comando com sucesso, o arquivo VideoChat.csproj deverá incluir as referências de pacote em um node (nó) <ItemGroup>
como exibido abaixo. (Os números de versão no projeto podem ser posteriores).
Criar a pasta e a estrutura de arquivos
Crie as seguintes pastas e arquivos:
/Abstractions
IVideoService.cs
/Hubs
NotificationHub.cs
/Models
RoomDetails.cs
/Options
TwilioSettings.cs
/Services
VideoService.cs
Quando terminar, a pasta Solution Explorer e a estrutura de arquivos devem ter esta aparência:
No diretório /Controllers , renomeie SampleDataController.cs como VideoController.cs e atualize o nome da classe para corresponder ao novo nome do arquivo.
Criar serviços
O código do lado do servidor precisa fazer várias coisas importantes, uma delas é fornecer um JSON Web Token (JWT) para que o cliente se conecte à API do Twilio Programmable Video. Para isso, são necessários o Account SID (SID da conta) Twilio, a API Key (chave de API) e o API Secret (segredo de API) armazenados como variáveis de ambiente. No ASP.NET Core, é comum aproveitar uma classe C# fortemente tipada para representar as várias configurações.
Adicione o seguinte código C# ao arquivo Options/TwilioSettings.cs abaixo das declarações:
Essas configurações são definidas no método Startup.ConfigureServices
, que mapeia os valores das variáveis de ambiente e do arquivo appsettings.json para as instâncias IOptions<TwilioSettings>
disponíveis para injeção de dependência. Nesse caso, as variáveis de ambiente são os únicos valores necessários para a classe TwilioSettings
.
No arquivo Models/RoomDetails.cs, abaixo das declarações, insira o código C# a seguir:
A classe RoomDetails
é um objeto que representa uma sala de chat por vídeo.
Tendo em mente a injeção de dependência, crie uma abstração para o serviço de vídeo do lado do servidor como uma interface.
Substitua os conteúdos do arquivo Abstractions/IVideoService.cs pelo seguinte código no C#:
Essa é uma interface muito simples que revela a capacidade de obtenção do JWT da Twilio ao receber uma identidade, além de oferecer a capacidade de obtenção de todas as salas.
Para implementar a interface IVideoService
, substitua os conteúdos do arquivo Services/VideoService.cs pelo seguinte código:
O construtor de classe VideoService
usa uma instância IOptions<TwilioSettings>
e inicializa o TwilioClient
, considerando a API Key (chave de API) fornecida e o API Secret (segredo de API) correspondente. Isso é feito de maneira estática e permite o uso posterior de várias funções baseadas em recursos. A implementação do GetTwilioJwt
é usada para emitir um novo Twilio.Jwt.AccessToken.Token
, considerando o Account SID (SID da conta), a API Key (chave da API), o API Secret (segredo da API), a identidade e uma nova instância HashSet<IGrant>
com um único objeto VideoGrant
. Antes de retornar, uma chamada da função .ToJwt
converte a instância do token em sua string
equivalente.
A função GetAllRoomAsync
retorna uma lista de objetos RoomDetails
. Ele começa aguardando a função RoomResource.ReadAsync
, que produzirá um ResourceSet<RoomResource>
. Nesta lista de salas, o código projeta uma série de Task<RoomDetails>
, onde solicitará o ResourceSet<ParticipantResource>
correspondente atualmente conectado à sala especificada com o identificador da sala room.UniqueName
.
Talvez você perceba alguma sintaxe desconhecida na função GetAllRoomsService
se não estiver acostumado a codificar após a declaração return
. O C# 8 inclui um recurso de função local estática que permite que as funções sejam escritas dentro do escopo do corpo do método ("localmente"), mesmo após a declaração de retorno. Elas são estáticas para garantir que as variáveis não sejam capturadas dentro do escopo de fechamento.
Observe que para cada sala n existente, GetRoomDetailsAsync
é chamado para buscar os participantes conectados da sala. Isso pode ser preocupante para o desempenho! Embora isso seja feito de forma assíncrona e paralela, deve ser considerado um possível gargalo e marcado para refatoração. Não é uma preocupação neste projeto de demonstração, pois existem apenas algumas salas.
Criar o controlador de API
O controller (controlador) de vídeo fornecerá dois endpoints HTTP GET para o cliente Angular usar.
Endpoint |
Verbo |
Tipo |
Descrição |
api/video/token |
GET |
JSON |
um objeto com um membro |
api/video/rooms |
GET |
JSON |
matriz de detalhes da sala: |
Substitua o conteúdo do arquivo Controllers/VideoController.cs pelo seguinte código C#:
O controller (controlador) é decorado com o atributo ApiController
e um atributo Route
contendo o modelo "api/video"
.
No constructor (construtor) VideoController
, o IVideoService
é injetado e atribuído a uma instância de campo readonly
.
Criar o hub de notificação
O aplicativo ASP.NET Core estaria incompleto sem o uso do SignalR, que "... é uma biblioteca de open source que simplifica a adição de funcionalidades da Web a aplicativos em tempo real. A funcionalidade da Web em tempo real permite que o código do lado do servidor envie conteúdo aos clientes instantaneamente".
Quando um usuário cria uma sala no aplicativo, o código do lado do cliente notifica o servidor e, por fim, outros clientes da nova sala. Isso é feito com um hub de notificação SignalR.
Substitua o conteúdo do arquivo Hubs/NotificationHub.cs pelo seguinte código C#:
O NotificationHub
enviará uma mensagem de forma assíncrona a todos os outros clientes notificando-os quando uma sala for adicionada.
Configure o Startup.cs
É necessário adicionar e alterar algumas coisas na classe Startup
e no método ConfigureServices
.
Adicione as seguintes declarações C# using
na parte superior do Startup.cs:
No método ConfigureServices
, substitua todo o código existente pelo seguinte código:
Isso define as configurações do aplicativo que contêm as credenciais da API da Twilio, mapeia a abstração do serviço de vídeo para sua implementação correspondente, atribui o caminho raiz do SPA e adiciona o SignalR.
No método Configure
, substitua a chamada app.UseEndpoints
pelas seguintes linhas:
Isso mapeia o endpoint de notificação para a implementação do NotificationHub
. Usando esse endpoint, o SPA do Angular em execução nos navegadores do cliente pode enviar mensagens para todos os outros clientes. O SignalR fornece a infraestrutura de notificação para esse processo.
Isso conclui a configuração do lado do servidor. Compile o projeto e verifique se não há erros.
Criar o aplicativo Angular do lado do cliente
Os modelos do ASP.NET Core não são atualizados regularmente; o Angular é atualizado constantemente. Para criar o app do cliente com o código Angular mais recente, o melhor é começar com um modelo Angular atual.
Exclua o diretório ClientApp do projeto VideoChat.
Abra uma janela do console (console do Windows ou PowerShell) no diretório do projeto VideoChat e execute o seguinte comando da CLI do Angular:
Esse comando deve criar uma pasta ClientApp no projeto VideoChat, com a estrutura básica de pastas e arquivos de um aplicativo Angular.
O aplicativo Angular tem várias dependências, incluindo os pacotes twilio-video
e @microsoft/signalr
. Suas dependências de desenvolvimento incluem as definições de tipo para @types/twilio-video
.
Substitua o conteúdo do package.json pelo seguinte código JSON:
Com as atualizações do package.json concluídas, execute a seguinte instrução de linha de comando do npm no diretório ClientApp:
Esse comando garante o download e a instalação de todas as dependências de JavaScript necessárias.
Abra o arquivo /ClientApp/src/index.html e observe o elemento <app-root>
. Esse elemento não padrão é usado pelo Angular para renderizar o aplicativo Angular na página HTML. O elemento app-root
é o seletor do componente AppComponent
.
Adicione a seguinte marcação HTML ao arquivo index.html, no elemento <head>
abaixo do elemento <link>
para o favicon:
Essa marcação permite que o aplicativo use a versão gratuita do Font Awesome e o tema Bootswatch Darkly.
Continue no arquivo /src/app/app.component.html e substitua o conteúdo pela seguinte marcação HTML:
Na linha de comando no diretório ClientApp, execute os seguintes comandos da CLI do Angular para gerar os componentes:
Em seguida, execute os seguintes comandos da CLI do Angular para gerar os serviços necessários:
Esses comandos adicionam todo o código padrão, permitindo que você se concentre na implementação do app. Eles adicionam novos componentes e serviços e atualizam o arquivo app.module.ts ao importar e declarar os componentes que os comandos criam.
A estrutura de pastas e arquivos deve ter a seguinte aparência:
Atualizar o módulo do app Angular
O aplicativo depende de dois módulos adicionais: um para implementar formulários e o outro para usar HTTP.
Adicione as duas instruções de importação a seguir à parte superior do ClientApp/src/app/app.module.ts:
Em seguida, adicione esses módulos a matriz imports
do @NgModule
como exibido:
Adicione polyfills JavaScript
Um projeto JavaScript estaria incompleto sem polyfills, certo? O mesmo ocorre com o Angular. Felizmente, as ferramentas do Angular dispõem de um arquivo polyfill.
Adicione o seguinte JavaScript à parte inferior do arquivo ClientApp/src/polyfill.ts existente:
Criar serviços Angular
A classe DeviceService
fornecerá informações sobre os dispositivos de mídia usados no aplicativo, incluindo sua disponibilidade e se o usuário concedeu permissão ao app para usá-los.
Substitua o conteúdo do arquivo services/device.service.ts pelo seguinte código TypeScript:
Este serviço fornece dispositivos de mídia observáveis aos quais os ouvintes interessados podem se inscrever. Quando as informações do dispositivo de mídia são alteradas, como desconectar ou conectar uma câmera da Web USB, esse serviço notificará todos os ouvintes. Ele também tenta aguardar que o usuário conceda permissões aos vários dispositivos de mídia consumidos pelo SDK twilio-video
.
O VideoChatService
é usado para acessar os endpoints da API da Web do ASP.NET Core no lado do servidor. Ele expõe a capacidade de obtenção da lista de salas e de criação ou participação em uma sala nomeada.
Substitua o conteúdo do arquivo services/videochat.service.ts pelo seguinte código TypeScript:
Observe que a recuperação do Twilio JWT é marcada como private
. O método getAuthToken
é usado somente na classe VideoChatService
para a chamada de connect
do módulo twilio-video
, que é feito de forma assíncrona no método joinOrCreateRoom
.
Conceitos gerais
Agora que os principais serviços estão implementados, como eles devem interagir uns com os outros e como eles devem se comportar? Os usuários precisam ser capazes de criar ou ingressar em salas. Uma sala é um recurso da Twilio e pode ter um ou mais participantes. Um participante também é um recurso da Twilio. Da mesma forma, os participantes têm publicações de faixas que fornecem acesso a faixas de mídia de vídeo e áudio. Os participantes e as salas compartilham câmeras que fornecem publicações de faixas de áudio e vídeo. O app tem componentes do Angular para cada um deles.
Implementar o componente Camera
Além de fornecer faixas de áudio e vídeo para os participantes da sala compartilharem, o CameraComponent
também permite visualizar a câmera local. Ao renderizar faixas de áudio e vídeo criadas localmente para o DOM como o elemento <app-camera>
. O SDK da plataforma de JavaScript do Twilio Programmable Video, importado do twilio-video
, fornece uma API fácil de usar para criar e gerenciar as faixas locais.
Substitua o conteúdo do arquivo camera/camera.component.ts pelo seguinte código TypeScript:
Substitua o conteúdo do arquivo camera/camera.component.html pela seguinte marcação HTML:
No código TypeScript acima, o decorador Angular @ViewChild
é usado para obter uma referência ao elemento HTML #preview
usado na visualização. Com a referência ao elemento, o SDK JavaScript da Twilio pode criar faixas de vídeo e áudio locais associadas ao dispositivo.
Depois que as faixas são criadas, o código encontra a faixa de vídeo e a anexa ao elemento #preview
. O resultado é um feed de vídeo ao vivo renderizado na página HTML.
Implementar o componente Rooms
O RoomsComponent
fornece uma interface para que usuários criem salas inserindo um roomName
por meio de um elemento <input type=’text’>
e um elemento <button>
vinculados ao método onTryAddRoom
da classe. A interface do usuário tem a seguinte aparência:
À medida que os usuários adicionam salas, a lista de salas existentes será exibida abaixo dos controles de criação de sala. O nome de cada sala existente serão exibidos junto com o número de participantes ativos e a capacidade da sala, como no exemplo mostrado abaixo.
Para implementar a interface de usuário das salas, substitua a marcação no arquivo rooms/rooms.component.html pela seguinte marcação HTML:
O RoomsComponent
inscreve-se no videoChatService.$roomsUpdated
observável. Sempre que uma sala for criada o RoomsComponent
sinalizará sua criação através do observável e o serviço NotificationHub
ouvirá. Usando o SignalR, o NotificationHub
transmite essa mensagem para todos os outros clientes conectados. Esse mecanismo permite que o código do lado do servidor forneça funcionalidade da Web em tempo real aos apps do cliente. Neste aplicativo, o RoomsComponent
atualizará automaticamente a lista de salas disponíveis.
Para implementar a funcionalidade RoomsComponent
, substitua o conteúdo do arquivo rooms/rooms.component.ts pelo seguinte código TypeScript:
Na realidade, quando um usuário seleciona uma sala para ingressar ou cria uma sala, ele se conecta a ela por meio do SDK twilio-video
.
O RoomsComponent
espera um nome de sala e uma matriz de objetos LocalTrack
. Essas faixas locais vêm da visualização da câmera local, que fornece uma faixa de áudio e vídeo. Os objetos LocalTrack
são publicados em salas nas quais um usuário participa para que outros participantes possam participar e recebê-los.
Implementar o componente Participants
O que há de bom em uma sala sem participantes? É apenas uma sala vazia, não tem graça!
Mas as salas têm algo muito legal: elas ampliam EventEmitter
. Isso significa que uma sala permite a inscrição como ouvintes de eventos.
Para implementar o ParticipantsComponent
, substitua o conteúdo do arquivo participants/participants.component.ts pelo seguinte código TypeScript:
O ParticipantComponent
também estende um EventEmitter
e oferece seu próprio conjunto de eventos relevantes. Entre a sala, o participante, a publicação e a faixa, há todo um conjunto de eventos para lidar quando os participantes entram ou saem de uma sala. Quando eles entram, um evento é acionado e fornece detalhes da publicação de suas faixas para que o aplicativo possa renderizar seu áudio e vídeo para a interface do usuário do DOM de cada cliente à medida que as faixas se tornam disponíveis.
Para implementar a interface do usuário para o componente participantes, substitua o conteúdo do arquivo participants/participants.component.html pela seguinte marcação HTML:
Assim como o CameraComponent
, os elementos de áudio e vídeo associados a um participante são alvos de renderização para o elemento #list
do DOM. Mas em vez de serem faixas locais, estas são faixas remotas publicadas por participantes remotos.
Implementar o gerenciamento de configurações do dispositivo
Há alguns componentes em jogo com o conceito de configurações. Teremos um componente camera
sob vários objetos DeviceSelectComponents
.
Substitua o conteúdo do arquivo settings/settings.component.ts pelo seguinte código TypeScript:
O objeto SettingsComponent
obtém todos os dispositivos disponíveis e os vincula aos objetos DeviceSelectComponent
dos quais ele é o pai. Conforme as seleções do dispositivo de entrada de vídeo mudam, a visualização do componente da câmera local é atualizada para refletir essas alterações. O observável deviceService.$devicesUpdated
é acionado à medida em que há alterações na disponibilidade do dispositivo no nível do sistema. A lista de dispositivos disponíveis é atualizada de acordo.
Para implementar a interface do usuário para configurações, substitua o conteúdo do arquivo settings/settings.component.html pela seguinte marcação HTML:
Caso a opção do dispositivo de mídia não esteja disponível para seleção, o objeto DeviceSelectComponent
não será renderizado. Quando uma opção está disponível, o usuário pode configurar o dispositivo desejado.
Conforme o usuário altera o dispositivo selecionado, o componente emite um evento para os ouvintes ativos, permitindo que eles executem uma ação neste dispositivo. A lista de dispositivos disponíveis é atualizada dinamicamente à medida que os dispositivos são conectados ou removidos do computador do usuário.
O usuário também visualiza o dispositivo de vídeo selecionado, como exibido abaixo:
Para implementar a interface de usuário de configurações, substitua os conteúdos do arquivo settings/device-select.component.ts pelo seguinte código TypeScript:
Substitua o conteúdo do arquivo settings/device-select.component.html file pela seguinte marcação HTML:
O objeto DeviceSelectComponent
destina-se a encapsular a seleção de dispositivos. Em vez de sobrecarregar o componente de configurações com redundância, um único componente é reutilizado e parametrizado com os decoradores @Input
e @Output
.
Implementar o componente Home
O HomeComponent
atua como a peça de orquestração entre os vários componentes e é responsável pelo layout do aplicativo.
Para implementar a interface de usuário inicial, substitua o conteúdo do arquivo home/home.component.ts pelo seguinte código de TypeScript:
Para implementar a interface do usuário inicial, substitua o conteúdo do arquivo home/home.component.html pela seguinte marcação HTML:
O componente home fornece o layout para a interface do usuário do cliente, portanto, ele precisa de um estilo para organizar e formatar os elementos da interface do usuário.
Substitua o conteúdo do arquivo home/home.component.css pelo seguinte código CSS:
Entenda os eventos de chat por vídeo
O app do cliente Angular utiliza vários recursos no SDK do Twilio Programmable Video. Veja abaixo uma lista abrangente de cada evento associado a um recurso do SDK:
Registro de eventos |
Descrição |
|
Ocorre quando um usuário sai da sala |
|
Ocorre quando um novo participante entra na sala |
|
Ocorre quando um participante sai da sala |
|
Ocorre quando uma faixa é publicada |
|
Ocorre quando uma faixa não é publicada |
|
Ocorre na inscrição de uma faixa |
|
Ocorre quando a inscrição de uma faixa é cancelada |
Coloque tudo em funcionamento
UFA, esse foi um projeto e tanto! É hora de experimentar.
Execute o aplicativo. Caso execute o aplicativo no Visual Studio 2019 usando o IIS Express, a interface do usuário será exibida em uma porta atribuída aleatoriamente. Se você executar de outra forma, acesse: https://localhost:5001.
Depois que o aplicativo carregar, o navegador solicitará permissão para acessar a câmera. Conceda o acesso.
Caso possua duas fontes de vídeo no computador, abra dois navegadores diferentes, ou uma janela anônima e selecione dispositivos diferentes em cada navegador. As configurações permitem que você escolha a fonte de entrada de vídeo preferida. Em um navegador, crie uma sala e, em seguida, entre na sala pelo outro navegador.
Ao criar uma sala, a visualização local move-se para baixo das configurações, de forma que a transmissão de vídeo dos novos participantes seja renderizada na área de visualização maior.
Se você não tiver duas fontes de vídeo no computador, o próximo post o ensinará a implantar esse aplicativo no Microsoft Azure. Uma vez que o app estiver implantado na nuvem, será possível que vários usuários ingressem em salas de chat por vídeo.
Resumo de como criar um app de chat por vídeo com ASP.NET Core, Angular e Twilio
Neste post, vimos como criar um aplicativo de chat por vídeo em total funcionamento com Angular, ASP.NET Core, SignalR e o Twilio Programmable Video. O SDK .NET da Twilio fornece JWTs ao código Angular do lado do cliente, além de obter os detalhes da sala por meio da API da Web ASP.NET Core. O Angular SPA do lado do cliente integra o SDK JavaScript da Twilio.
Recursos adicionais
Um exemplo funcional do aplicativo está disponível no domínio Azure do autor https://ievangelist-videochat.azurewebsites.net/
O repositório complementar do GitHub possui melhor estilo, seleções persistentes e outros recursos que você pode querer incluir em seu app de produção.
Saiba mais sobre as tecnologias usadas neste post a partir das seguintes fontes:
- Observables (Observáveis) e Promises (Promessas) do Angular: Observables no angular.io, Understanding, creating and subscribing to observables in Angular e AngularJS Promises – The Definitive Guide no Medium
- Funções locais do no C# : Local functions (C# Programming Guide) em docs.microsoft.com
Publicações relacionadas
Recursos relacionados
Twilio Docs
De APIs a SDKs e aplicativos de amostra
Documentação de referência de API, SDKs, bibliotecas auxiliares, guias de início rápido e tutoriais para sua linguagem e plataforma.
Centro de Recursos
Os mais recentes e-books, relatórios do setor e webinars
Aprenda com especialistas em engajamento do cliente para melhorar sua própria comunicação.
Ahoy
Centro da comunidade de desenvolvedores da Twilio
Melhores práticas, exemplos de código e inspiração para criar comunicações e experiências de engajamento digital.