Flutter SignalR: Comunicação em Tempo Real

Flutter SignalR, vamos ver como implmentar a comunicação em tempo real entre aplicativos Web e Mobile utilizando estas tecnologias.

Pré-Requisitos

Para realizar este tutorial, você precisa do Flutter instalado e já ter dado alguns passos com ele. Se você ainda não começou com Flutter, segue nosso artigo para dar seus primeiros passos.

Para o lado do servidor, precisaremos do .NET Core instalado, se você ainda não tem ele ou o Visual Studio Code, faça a instalação de ambos antes de prosseguir.

Vamos começar com Flutter SignalR?

ASP.NET Core SignalR

O SignalR é um pacote que anda em conjunto com o ASP.NET Core e permite trabalharmos com comunicação em tempo real entre nossas aplicações utilizando WebSockets.

O SignalR funciona no modelo cliente/servidor, onde temos nosso servidor servindo mensagens para um indivíduo ou um grupo e diversos clientes consumindo estas mensagens.

Os grupos no SignalR são chamados de Hubs, e eles funcionam de fato como grupos de distribuição de mensagens. Basta enviar uma mensagem para um grupo e ele se encarrega de entregar.

Além dos Hubs, podemos enviar uma mensagem para um indivíduo em específico, direcionando a mensagem para seu nome de usuário.

Fora isto, podemos invocar as funções que estão em nossos Hubs diretamente dos clientes, utilizando bibliotecas para isto, como o flutter_signalr que veremos aqui.

Para cada cliente (Desktop, Web, Mobile) é necessário uma biblioteca diferente para comunicação com nosso Hub, mas o SignalR provê muitas delas já prontas.

Flutter SignalR: Criando o Servidor

Nosso primeiro passo aqui é criar nosso servidor de mensagens, que será responsável por receber e enviar as informações para nossos Apps.

Criando o Projeto

Vamos iniciar criando nosso projeto com auxílio do dotnet-cli, via linha de comando, executando o seguinte.

dotnet new webapp -o SignalRChat

Este comando vai criar uma aplicação Web utilizando ASP.NET Core e Razor Pages. Para este cenário, não importa muito o tipo do projeto (Razor Pages, MVC, etc..).

Abra este projeto com o Visual Studio Code e estaremos prontos para começar.

Caso esteja com dificuldades na criação do projeto ou seja seu primeiro contato com ASP.NET Core, realize nossa carreira Backend .NET Developer antes.

Adicionando SignalR

Como comentamos previamente, o SignalR é um biblioteca que age em conjunto com o ASP.NET Core, e ela é dividia em duas partes, cliente e servidor.

Neste caso, vamos instalar ambas bibliotecas neste projeto, mas você poderia deixar apenas o servidor rodando aqui e o cliente sendo uma outra aplicação.

Neste caso, você poderia tanto realizar a instalação como faremos aqui e depois copiar os arquivos JavaScript, necessários para o cliente se conectar ao servidor para sua aplicação, quanto utilizar um CDN.

O pacote do SignalR está distribuído através do Nuget, e já vem no pacote do ASP.NET Core, porém, os scripts (JavaScript) utilizados pelo cliente não.

O Flutter SignalR por exemplo será obtido de um pacote criado por terceiros, previamente neste artigo.

Podemos obtê-los utilizando o Libman, executando os seguintes passos.

dotnet tool install -g Microsoft.Web.LibraryManager.Cli
libman install @microsoft/signalr@latest -p unpkg -d wwwroot/js/signalr --files dist/browser/signalr.js --files dist/browser/signalr.min.js

Desta forma, o Libman fará o download dos arquivos e já os colocará nas pastas corretas da nossa aplicação Web.

Ao término da execução você deverá ver um resultado parecido com este.

wwwroot/js/signalr/dist/browser/signalr.js written to disk
wwwroot/js/signalr/dist/browser/signalr.min.js written to disk
Installed library @microsoft/signalr@lates to wwwroot/js/signalr

Criando um Hub

Com os pacotes adicionados, vamos agora criar o nosso Hub, que é o grupo de distribução que utilizaremos.

Desta forma, vamos criar uma nova pasta chamada Hubs e um arquivo chamado ChatHub.cs dentro dela, com o seguinte conteúdo.

using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks;

namespace SignalRChat.Hubs
{
    public class ChatHub : Hub
    {
        public async Task SendMessage(string user, string message)
        {
            await Clients.All.SendAsync("ReceiveMessage", user, message);
        }
    }
}

Um Hub nada mais é do que uma classe que herda da classe base Hub. Esta classe contém métodos como o SendMessage que poderemos invocar dos clientes posteriormente.

Para disseminar a mensagem podemos utilizar o Clients, que pode tanto enviar uma mensagem para um indivíduo em específico, quanto para um grupo, quanto para todos.

Neste caso, estamos utilizando o Clients.All para enviar o usuário e a mensagem que recebemos para TODOS que estão conectados a este servidor.

Configurando o SignalR

Nosso próximo passo é configurar nossa aplicação para utilizar o SignalR, e isto requer apenas três passos, sendo o primeiro, a adição do Namespace do SignalR no topo do arquivo Startup.cs.

using SignalRChat.Hubs;

Em seguida, vamos adicionar o serviço do SignalR no método ConfigureServices, logo após o services.AddRazorPages.

services.AddSignalR();

E por fim, vamos mapear as rotas do nosso Hub no método Configure, adicionando a linha abaixo logo após o endpoints.MapRazorPages.

app.UseEndpoints(endpoints =>
{
    endpoints.MapRazorPages();
    endpoints.MapHub<ChatHub>("/chatHub"); // Linha adicionada
});

Note que ao configurar um endpoint utilizando o MapHub, passamos seu nome, que será concatenado com a URL padrão da nossa aplicação, neste caso https://localhost:5001.

Isto quer dizer que qualquer requisição para nosso Hub deve ser feita com base na URL https://localhost:5001/chatHub.

Configurando o Cliente Web

Com o SignalR instalado e configurado, vamos agora criar um cliente Web simples apenas para testá-lo. Não vamos nos prender ao HTML/CSS dele, o foco aqui é comunicação com Flutter.

Desta forma, substitua o conteúdo do arquivo Pages/index.cshtml pelo conteúdo abaixo.

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="container">
    <div class="row">&nbsp;</div>
    <div class="row">
        <div class="col-2">User</div>
        <div class="col-4"><input type="text" id="userInput" /></div>
    </div>
    <div class="row">
        <div class="col-2">Message</div>
        <div class="col-4"><input type="text" id="messageInput" /></div>
    </div>
    <div class="row">&nbsp;</div>
    <div class="row">
        <div class="col-6">
            <input type="button" id="sendButton" value="Send Message" />
        </div>
    </div>
</div>
<div class="row">
    <div class="col-12">
        <hr />
    </div>
</div>
<div class="row">
    <div class="col-6">
        <ul id="messagesList"></ul>
    </div>
</div>

<script src="~/js/signalr/dist/browser/signalr.js"></script>
<script src="~/js/chat.js"></script>

Nesta página temos apenas três elementos que importam, um Input para o usuário, um Input para mensagem e um botão que vai enviar a mensagem para nosso servidor.

Ao final da página temos duas chamadas JavaScript, uma para o arquivo que foi baixado pelo Libman previamente (/js/signalr/dist/browser/signalr.js) e outro para o arquivo chat.js que ainda não criamos.

Caso queira separar seu Frontend do servidor, basta copiar o signalr.js e chat.js que mencionados nas inclusões acima para seu projeto separado.

Como nosso foco aqui é o Flutter, não vou entrar em detalhes sobre a implementação em JavaScript da comunicação desta aplicação com o servidor. Podemos tratar isto em outro artigo.

Desta forma, vamos criar um novo arquivo em wwwroot/js/chat.js com o seguinte código.

"use strict";

var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();

//Disable send button until connection is established
document.getElementById("sendButton").disabled = true;

connection.on("ReceiveMessage", function (user, message) {
    var msg = message.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
    var encodedMsg = user + " says " + msg;
    var li = document.createElement("li");
    li.textContent = encodedMsg;
    document.getElementById("messagesList").appendChild(li);
});

connection.start().then(function () {
    document.getElementById("sendButton").disabled = false;
}).catch(function (err) {
    return console.error(err.toString());
});

document.getElementById("sendButton").addEventListener("click", function (event) {
    var user = document.getElementById("userInput").value;
    var message = document.getElementById("messageInput").value;
    connection.invoke("SendMessage", user, message).catch(function (err) {
        return console.error(err.toString());
    });
    event.preventDefault();
});

Executando a aplicação

Isto é tudo que precisamos para ter um chat funcionando com ASP.NET Core, SignalR e JavaScript (Aplicação Web), e você já pode testar executando o seguinte comando.

dotnet watch run

Se tudo deu certo, ao abrir seu Browser no endereço https://localhost:5001 você verá a aplicação rodando e conseguirá enviar mensagens. Abra diversos Browsers e verá que eles se comunicam entre si.

Caso ocorra algum erro de certificado, você pode executar as seguintes linhas de comando para aceitar os certificados utilizados pelas aplicações ASP.NET Core.

dotnet dev-certs https --clean
dotnet dev-certs https --trust

Flutter SignalR: Criando o App

Agora vamos focar nossos esforços em fazer o Flutter se conectar ao nosso servidor e possibilitar o recebimento de mensagens em tempo real em nosso App.

Criando o App

O primeiro passo é criar um App novo em branco, então abra o Visual Studio Code, execute o comando CTRL(CMD)+SHIFT+P e selecione Flutter New Project.

Caso queira seguir o mesmo nome, nosso App utilizou flusigr, desta forma seu código será totalmente compatível com o nosso. Não esqueça de abrir seu Emulador preferido ou conectar-se ao seu telefone para rodar o App.

Instalando o pacote

Como comentamos anteriormente, para se conectar ao servidor, precisamos de um cliente, e no caso do Flutter este pacote se chama signalr_client.

Desta forma, vamos abrir o nosso pubspect.yaml e adicionar a seguinte referência.

dependencies:
    flutter:
        sdk: flutter

    # The following adds the Cupertino Icons font to your application.
    # Use with the CupertinoIcons class for iOS style icons.
    cupertino_icons: ^0.1.2
    signalr_client: ^0.1.6 # Referência do signalR

Isto é tudo que precisamos no momento, vamos agora rodar nossa aplicação para testar se tudo está funcionando. Como resultado, você deve ver a aplicação padrão que o Flutter nos cria, com um contador na tela.

Aceitando certificados HTTPS inválidos

O primeiro problema que vamos enfrentar é que nosso servidor está sobre HTTPS mas não tem um certificado válido. Isto implicará em um erro de certificado que temos que corrigir antes de começar.

O que vamos fazer é sobrescrever as requisições HTTP do nosso App, aceitando os certificados inválidos. Este código na verdade não faz parte de nada do SignalR e talvez você não passe por este problema.

Desta forma, vamos alterar o método main do arquivo main.dart para executar a ação que mencionamos acima.

import 'dart:io';

// Esta classe permite acesso ao LocalHost com certificados HTTPS inválidos
class MyHttpOverrides extends HttpOverrides {
    @override
    HttpClient createHttpClient(SecurityContext context) {
        HttpClient client = super.createHttpClient(context);
        client.badCertificateCallback =
            (X509Certificate cert, String host, int port) => true;
        return client;
    }
}

void main() {
    HttpOverrides.global = new MyHttpOverrides();
    runApp(MyApp());
}

Com este acesso garantido, nosso servidor estará disponível no seguinte endereço https://10.0.2.2:5001/chatHub, onde 10.0.2.2 é o endereço do LocalHost mapeado dentro do emulador e /chatHub é o endereço do Hub que criamos no servidor.

IMPORTANTE: Não se esqueça de deixar o servidor rodando, utilizando o comando dotnet watch run na outra instância do Visual Studio Code ou em algum terminal.

Flutter SignalR: Conectando ao Servidor

O primeiro passo para nos conectarmos Flutter SignalR é fazer a importação da biblioteca que instalamos previamente, o signalr_client.

import 'package:signalr_client/signalr_client.dart';

Com esta importação, podemos utilizar o HubConnectionBuilder pare realizar a conexão e posteriormente ficar ouvindo/enviando as mensagens.

A instância do HubConnectionBuilder por sua vez, exige uma URL, que vimos previamente aqui. Vamos então criar uma nova instância dele já no começo da nossa classe _MyHomePageState.

class _MyHomePageState extends State<MyHomePage> {
    final hubConnection = HubConnectionBuilder().withUrl("https://10.0.2.2:5001/chatHub").build();
    ...

Note que utilizamos o método withUrl informando a URL do nosso servidor, que no caso é https://10.0.2.2:5001/chatHub.

Por fim, precisamos iniciar esta conexão, e o melhor lugar para isto é durante a inicialização do nosso componente, no método initState.

Porém, o método que inicia a conexão é assíncrono, e o initState não, então vamos criar um método separado, chamado startConnection e chamá-lo no initState.

class _MyHomePageState extends State<MyHomePage> {
    final hubConnection = HubConnectionBuilder().withUrl("https://10.0.2.2:5001/chatHub").build();
    
    @override
    void initState() {
        super.initState();
        startConnection();
    }
    
    void startConnection() async {
        await hubConnection.start(); // Inicia a conexão ao servidor
    }
    ...

Flutter SignalR: Ouvindo as Mensagens

Nosso desafio agora é ouvir as mensagens que estão sendo enviadas pelo servidor, e para isto utilizaremos a instância do HubConnectionBuilder que acabamos de criar.

Toda vez que recebemos uma mensagem, temos uma lista de objetos e caso seu servidor envie um JSON, você pode tipar esta lista de objetos aqui também.

Neste caso o pacote signalr_client vai utilizar o dart:convert para tentar converter seu JSON para objeto, ou seja, seu objeto precisa ter o método fromJson.

No nosso caso, vamos trabalhar com lista de objetos mesmo, sendo o primeiro o usuário e o segundo a mensagem que ele enviou.

Para iniciar, vamos criar um método chamado onReceiveMessage que recebe uma lista de objetos como retorno.

void onReceiveMessage(List<Object> result) {
    print(result);
}

Agora tudo que precisamos fazer é utilizar o método on do HubConnectionBuilder para ficar ouvindo um Hub do nosso servidor, e sempre que uma nova mensagem chegar ele chamará nosso método acima.

@override
void initState() {
    super.initState();

    hubConnection.onclose((_) {
        print("Conexão perdida");
    });

    hubConnection.on("ReceiveMessage", onReceiveMessage);

    startConnection();
}

Aproveitei para deixar a função onclose exibindo a mensagem 'conexão perdida' toda vez que nossa aplicação se desconectar do servidor.

Neste momento você pode rodar sua aplicação e testar o envio de mensagens da Web para seu App, ele deve printar as mensagens enviadas da aplicação Web no console do Flutter.

Flutter SignalR: Exibindo as Mensagens

Para exibir as mensagens na tela, vamos primeiro armazená-las em uma lista de Strings, então vamos criar esta variável no começo da classe também.

class _MyHomePageState extends State<MyHomePage> {
    final hubConnection = HubConnectionBuilder().withUrl("https://10.0.2.2:5001/chatHub").build();
    final List<String> messages = new List<String>();
    ...

Precisamos agora refatorar o método onReceiveMessage para popular esta lista, e vamos precisar utilizar o setState a cada mensagem recebida para que o Flutter atualize a tela.

void onReceiveMessage(List<Object> result) {
    setState(() {
        messages.add("${result[0]} diz: ${result[1]}");
    });
}

Note que estamos utilizando result[0] para o nome do usuário e result[1] para a mensagem. Se você quiser saber mais detalhes sobre o formato da mensagem, basta printá-la como anteriormente.

Vamos então utilizar um ListView.builder para exibir as mensagens na tela de forma dinâmica.

@override
Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
        title: Text(widget.title),
        ),
        body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: ListView.builder(
            itemCount: messages.length,
            itemBuilder: (ctx, i) {
            return Text(messages[i]);
            },
        ),
        ),
    );
}

Muito bem, neste momento você deve estar visualizando as mensagens enviadas do cliente Web no seu App em tempo real utilizando Flutter SignalR!

Flutter SignalR: Enviando Mensagens

Para enviar uma mensagem, precisaremos primeiro de um InputText, e para obter seu texto com facilidade, precisaremos de um TextEditingController.

class _MyHomePageState extends State<MyHomePage> {
    final controller = new TextEditingController(); // Adicionado esta linha
    final hubConnection = HubConnectionBuilder().withUrl("https://10.0.2.2:5001/chatHub").build();
    final List<String> messages = new List<String>();
    ...

Para enviar mensagens para nosso servidor, podemos utilizar novamente nosso HubConnectionBuilder, mas desta vez com o método Invoke, que será capaz de chamar um método definido no nosso ChatHub.cs lá no servidor.

void sendMessage() async {
    await hubConnection.invoke("SendMessage",
        args: <Object>["Flutter", controller.text]).catchError((err) {
        print(err);
    });
}

Neste caso, estamos chamando o método SendMessage que definimos, passando como argumentos um array de objetos, sendo o primeiro parâmetro uma string fixa, chamada Flutter e o segundo o texto que estará em nosso InputText.

Tudo que precisamos agora é de um InputText e um botão para chamar o método sendMessage que acabamos de criar.

@override
Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
            title: Text(widget.title),
        ),
        body: Padding(
            padding: const EdgeInsets.all(20.0),
                child: ListView.builder(
                    itemCount: messages.length,
                    itemBuilder: (ctx, i) {
                        return Text(messages[i]);
                    },
                ),
            ),
            bottomSheet: Container(
            color: Theme.of(context).accentColor,
            padding: EdgeInsets.all(20),
            height: 90,
            child: TextFormField(
                controller: controller,
                decoration: InputDecoration(labelText: "Mensagem..."),
            ),
        ),
        floatingActionButton: FloatingActionButton(
            child: Icon(Icons.send),
            onPressed: () {
                sendMessage();
            },
        ),
    );
}

O resultado final do arquivo main.dart fica no seguinte formato.

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:signalr_client/signalr_client.dart';

// Esta classe permite acesso ao LocalHost com certificados HTTPS inválidos
class MyHttpOverrides extends HttpOverrides {
    @override
    HttpClient createHttpClient(SecurityContext context) {
        HttpClient client = super.createHttpClient(context);
        client.badCertificateCallback =
            (X509Certificate cert, String host, int port) => true;
        return client;
    }
}

void main() {
    HttpOverrides.global = new MyHttpOverrides();
    runApp(MyApp());
}

class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            title: 'Flutter SignalR',
            theme: ThemeData(
                primarySwatch: Colors.blue,
            ),
            home: MyHomePage(title: 'Flutter SignalR'),
        );
    }
}

class MyHomePage extends StatefulWidget {
    MyHomePage({Key key, this.title}) : super(key: key);
    final String title;

    @override
    _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
    final controller = new TextEditingController();
    final hubConnection = HubConnectionBuilder().withUrl("https://10.0.2.2:5001/chatHub").build();
    final List<String> messages = new List<String>();

    @override
    void initState() {
        super.initState();

        hubConnection.onclose((_) {
            print("Conexão perdida");
        });

        hubConnection.on("ReceiveMessage", onReceiveMessage);

        startConnection();
    }

    void onReceiveMessage(List<Object> result) {
        setState(() {
            messages.add("${result[0]} diz: ${result[1]}");
        });
    }

    void startConnection() async {
        await hubConnection.start();
    }

    void sendMessage() async {
        await hubConnection.invoke("SendMessage", args: <Object>["Flutter", controller.text]).catchError((err) {
            print(err);
        });
    }

    @override
    Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
                title: Text(widget.title),
            ),
            body: Padding(
                    padding: const EdgeInsets.all(20.0),
                    child: ListView.builder(
                    itemCount: messages.length,
                    itemBuilder: (ctx, i) {
                        return Text(messages[i]);
                    },
                ),
            ),
            bottomSheet: Container(
                color: Theme.of(context).accentColor,
                padding: EdgeInsets.all(20),
                height: 90,
                child: TextFormField(
                    controller: controller,
                    decoration: InputDecoration(labelText: "Mensagem..."),
                ),
            ),
            floatingActionButton: FloatingActionButton(
                child: Icon(Icons.send),
                onPressed: () {
                    sendMessage();
                },
            ),
        );
    }
}

Agora é só executar a aplicação que você tem um chat funcionando entre sua aplicação Web e sua App Flutter.

Conclusão

Flutter SignalR podem trabalhar de forma conjunta e fácil. Neste artigo vimos o básico de como criar um Hub e enviar/receber mensagens por ele em aplicações Web ou Mobile.

O código fonte do servidor e do App desenvolvidos neste artigo você encontra aqui.

Fontes

Populares

Priority Queue

Priority Queue ou fila prioritária é um tipo de lista inclusa no C# 10 que permite que seus itens...


Implicit Operators no C#

Implicit Operators permitem adicionar comportamentos de conversão a objetos Built In ou complexos...


ASP.NET 5 – Autenticação e Autorização com Bearer e JWT

Este artigo atualmente utiliza a versão 5.0.0-rc.1 do ASP.NET/.NET, o que significa que ainda não...


Clean Code - Guia e Exemplos

Saiba como manter seu código limpo (Clean Code) seguindo algumas práticas sugeridas pelo Robert C...


Git e GitHub - Instalação, Configuração e Primeiros Passos

Git é um sistema de controle de versões distribuídas, enquanto GitHub é uma plataforma que tem o ...


Compartilhe este artigo



Conheça o autor

Me dedico ao desenvolvimento de software desde 2003, sendo minha maior especialidade o Desenvolvimento Web. Durante esta jornada pude trabalhar presencialmente aqui no Brasil e Estados Unidos, atender remotamente times da ?ndia, Inglaterra e Holanda, receber 8x Microsoft MVP e realizar diversas consultorias em empresas e projetos de todos os tamanhos.





2.985

Aulas disponíveis

279

horas de conteúdo

72.514

Alunos matriculados

50.112

Certificados emitidos





Comece de graça agora mesmo!

Temos mais de 20 cursos totalmente de graça e todos com certificado de conclusão.

Começar


Prefere algo mais Premium?

Conheça nossos planos



Premium anual

Compra única, parcelada em até
12x no cartão de crédito


12x R$

84

,78

=R$ 1.017,36
  • 1 ano de acesso
  • Acesso à todo conteúdo
  • Emissão de Certificado
  • Tira Dúvidas Online
  • 62 cursos disponíveis
  • 10 carreiras disponíveis
  • 161 temas de tecnologia
  • Conteúdo novo todo mês
  • Encontros Premium

Começar agora

Política de privacidade



Precisa de ajuda?

Dúvidas frequentes



  • Posso começar de graça?

    Sim! Basta criar sua conta gratuita no balta.io e começar seus estudos. Nós contamos com diversos cursos TOTALMENTE gratuitos e com certificado de conclusão.

  • Vou ter que pagar algo?

    Nós temos cursos gratuitos e pagos, porém você não precisa informar nenhum dado de pagamento para começar seus estudos gratuitamente conosco. Os cursos gratuitos são completos e com certificado de conclusão, você não paga nada por eles.

    Porém, caso queira algo mais Premium , você terá acesso à diversos benefícios que vão te ajudar ainda mais em sua carreira.

  • Por onde devo começar?

    Siga SEMPRE as nossas Carreiras , elas vão te orientar em todos os sentidos. Os cursos já estão organizados em categorias e carreiras para facilitar seu aprendizado.
    Nossa sugestão para aprendizado é começar pelo Backend e seguindo para Frontend e Mobile.

    • Backend
    • Frontend
    • Mobile

  • Os cursos ensinam tudo que preciso?

    Nenhum curso no mundo vai te ensinar tudo, desculpa ser sincero! Os cursos são uma base, eles fornecem por volta de 30% do que você precisa aprender, o resto é com você, com dedicação e MUITA prática.

  • O que eu devo estudar?

    Java ou .NET? Angular ou React? Xamarin ou Flutter? A resposta é simples e direta: "Você já sabe o básico?"

    Se você ainda não sabe BEM o básico, ou seja, os fundamentos, OOP, SOLID, Clean Code, está perdendo tempo estudando Frameworks ou até coisas mais avançadas como Docker. Foque nos seus objetivos primeiro.
    Agora se você está indeciso sobre qual Framework estudar, a boa notícia é que o mercado neste momento está bem aquecido e você tem várias oportunidade. Desta forma o que levaríamos em conta para tomar esta decisão seria:

    • Já sei o básico
    • O Framework/Tecnologia tem mercado onde eu estou (região)
    • O Framework/Tecnologia é utilizado em uma empresa onde quero atual
    • O Framework/Tecnologia resolve meu problema
    • Eu gosto de utilizar o Framework/Tecnologia

  • Estou pronto para estudar no balta.io?

    Com certeza! O primeiro passo é começar e você pode fazer isto agora mesmo!

    Começar de graça

Ainda tem dúvidas?





Assine nosso Newsletter

Receba em primeira mão todas as nossas novidades.

Cadastrar


balta.io