ASP.NET SignalR – Acompanhando o percentual de uso da CPU em tempo real

Standard

Atendendo alguns pedidos do Facebook e por email que recebi semana passada, hoje vou demostrar um exemplo de utilização do SignalR em uma aplicação que NÃO seja um chat. 🙂

Importante: Se você não sabe o que é o SignalR, nunca ouviu falar, ou não tem conhecimento, aconselho a leitura dos meus artigos anteriores sobre o assunto antes de continuar.

Situação Atual

Realmente a maioria dos artigos, posts e exemplos encontrados pela web demonstram a utilização do SignalR em aplicações de chat, muito bacana, isto facilita muito as coisas para quem precisa implementar algo do tipo, porém, tem um lado muito negativo: a maioria do pessoal vê vantagem em utiliza-lo apenas em aplicações de chat, ou algo relativamente simples. Porém, o SignalR é uma biblioteca ALTAMENTE completa e robusta, podendo ser utilizadas em diversos tipos de situações e projetos.

Particulamente utilizo o SignalR regularmente nos projetos que trabalho, e até hoje, nunca foi para criar um chat!

O que vamos criar?

Acredito que todos conheçam a classe PerformanceCounter presente dentro do namespace System.Diagnostics, onde é possível obter informações do desempenho atual da CPU, memória RAM, etc. Não vou entrar em detalhes de como funciona, pois além de ter muito conteúdo pela web, não é o foco do artigo de hoje.

Pois bem, utilizando a classe PerformanceCounter iremos enviar em tempo real utilizando o SignalR as informações de uso da CPU para todos os clientes conectados.

Step by step

Vamos começar criando um projeto em ASP.NET MVC4 com o template “Basic”, depois adicionaremos uma pasta chamada Hubs na raiz do nosso projeto e adicionaremos um novo Hub:

Veja, quando adicionarmos nosso Hub, todas os namespaces e scripts do SignalR serão adicionados automaticamente.

Em seguida criaremos uma classe para o monitoramento da CPU e a transmissão do percentual usado para os clientes, veja:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
namespace MVC4_SignalR_UsoCpuRealTime.Hubs
{
    /// <summary>
    /// Controla a exibição e transmissão do uso de CPU para os clients
    /// </summary>
    public class ControleCpu
    {
        private readonly static Lazy<ControleCpu> _instancia = new Lazy<ControleCpu>(() => new ControleCpu());
        private const int _intervalo = 1000; // 1 segundo
        private PerformanceCounter _cpu = new PerformanceCounter();

        public static ControleCpu Instancia
        {
            get
            {
                return _instancia.Value;
            }
        }

        private ControleCpu() {}


        public void RealizaTransmissaoUsoCPU()
        {
            // Definição básica para obter o uso da CPU
            _cpu.CategoryName = "Processor";
            _cpu.CounterName = "% Processor Time";
            _cpu.InstanceName = "_Total";

            // Cria timer para transmitir as informações de 1 em 1 seg
            new Timer(TransmiteParaTodosClientes, null, _intervalo, _intervalo);
        }
       
        private void TransmiteParaTodosClientes(object state)
        {
            // Transmite a informação para todos os clientes, chamando a função atualizaUsoCPU
            ObtemClientes<CpuHub>().All.atualizaUsoCPU(_cpu.NextValue());
        }

        /// <summary>
        /// Obtém os clientes conectados
        /// </summary>
        /// <typeparam name="T">Tipo do Hub</typeparam>
        /// <returns></returns>
        private IHubConnectionContext ObtemClientes<T>() where T : Hub
        {
            return GlobalHost.ConnectionManager.GetHubContext<T>().Clients;
        }
    }
}

Observe que estamos utilizando um Timer para o envio do percentual de CPU utilizado para TODOS os clientes em conexão de 1 em 1 segundo, simples e bacana o código, não?

Atente-se que estaremos invocando a função atualizaUsoCPU em client-side, posteriormente estaremos criando esta parte.

Agora iremos implementar nosso Hub:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
namespace MVC4_SignalR_UsoCpuRealTime.Hubs
{
    [HubName("cpuHub")]
    public class CpuHub : Hub
    {
        private readonly ControleCpu _controleCpu;

        public CpuHub() : this(ControleCpu.Instancia) { }

        public CpuHub(ControleCpu controle)
        {
            _controleCpu = controle;
        }

        /// <summary>
        /// Inicia a transmissão do uso da CPU do servidor
        /// </summary>
        public void IniciaTransmissaoUsoCpu()
        {
            _controleCpu.RealizaTransmissaoUsoCPU();
        }
    }
}

Note que este é um exemplo onde a transmissão com os clients NÃO é realizada em nosso Hub, mas sim na classe ControleCpu.

Agora vamos criar nossa View e o script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
@section scripts{
   
    <script src="~/Scripts/jquery.signalR-1.0.0.js"></script>
    <script src="~/signalr/hubs" type="text/javascript"></script>

    <script src="~/Scripts/smoothiecharts/smoothiecharts.js"></script>

    <script type="text/javascript">
           
            var registros = new TimeSeries();
           
            // Cria o proxy
            var chartHub = $.connection.cpuHub;
           
            // Define a função atualizaUsoCPU, esta função será invocada no broadcast de nosso Hub
            $.extend(chartHub.client, {
                atualizaUsoCPU: function (data) {
                   
                    // Atualiza o percentual usado de CPU
                    $("#lblUsoCPU").text(data + " %");

                    // Insere o pecentual usado no registro de séries no gráfico
                    registros.append(new Date().getTime(), data);
                }
            });

            // Inicia a conexão
            $.connection.hub.start(function () {
                chartHub.server.iniciaTransmissaoUsoCpu();
            });
           
            // Cria o gráfico e define suas opções e séries
            function criaLinhasNoGrafico() {
                var chart = new SmoothieChart();

                var opcoes = {
                    strokeStyle: 'rgba(255, 0, 0, 1)',
                    fillStyle: 'rgba(255, 0, 0, 0.2)',
                    lineWidth: 1
                };

                chart.addTimeSeries(registros, opcoes);
                chart.streamTo($("#chart").get(0), 1000);
            }

    </script>
}

<body onload="criaLinhasNoGrafico()">

    <h3>Uso da CPU:&nbsp;<label id="lblUsoCPU"></label></h3>
    <br />
    <canvas id="chart" width="800" height="300"></canvas>

</body>

Bem tranquilo né? Veja que definimos a função atualizaUsoCPU e quando a conexão é aberta, é invocado o método IniciaTransmissaoUsoCpu em nosso Hub.

Resultado

O código do projeto está no meu GitHub

Links

http://signalr.net/
http://www.asp.net/signalr
http://www.asp.net/mvc
http://smoothiecharts.org/

Leave a Reply

Your email address will not be published. Required fields are marked *