uniGUI & WebSockets

uniGUI integra a tecnologia WebSockets para permitir que desenvolvedores enviem mensagens diretamente aos clientes web a partir do servidor. A implementação de WebSockets do uniGUI é direta. Enviar mensagens do servidor para os clientes pode ser feito usando o método BroadcastMessage(). Quando chamado, uma mensagem e parâmetros relacionados são transmitidos pela rede uniGUI usando canais WebSocket. Essa transmissão incluirá todos os Nodes e servidores escravos em um cluster de servidor farm. O uniGUI retransmite automaticamente as mensagens para todas as instâncias de servidor ativas em um cluster de servidor farm. Cada servidor envia as mensagens aos seus próprios clientes web, garantindo que todas as sessões recebam as mensagens independentemente da complexidade do cluster.

Por exemplo, a chamada a seguir envia uma mensagem chamada "update" para todos os clientes existentes:

Delphi
BroadcastMessage('update');

Quando essa mensagem é recebida por um cliente web, esse cliente dispara uma requisição Ajax para o servidor. Consequentemente, no lado do servidor um manipulador de evento chamado OnBroadcastMessage será chamado:

Delphi
procedure TMainForm.UniFormBroadcastMessage(const Sender: TComponent;
  const Msg: string; const Params: TUniStrings);
begin
  if Msg = 'update' then
  begin
    UniLabel1.Caption := Query1.RecordCount.ToString;
  end;
end;

No exemplo acima, um UniLabel é atualizado cada vez que uma mensagem é recebida para mostrar a contagem atual de registros de uma consulta de banco de dados.

Mensagens podem ser enviadas de praticamente qualquer lugar na aplicação (eventos de usuário, outras threads, timers). Mensagens podem ser enviadas assincronamente de qualquer thread na aplicação. Em um cluster HyperServer, uma mensagem iniciada a partir de um Node será propagada automaticamente por todos os servidores no cluster.

Quando uma mensagem é enviada usando BroadcastMessage ela é enviada primeiro aos clientes web. Após a mensagem ser recebida pelo cliente, há duas maneiras de processá-la:

  • Processar a mensagem apenas no lado do cliente (manipulador de evento JavaScript).

  • Processar a mensagem no lado do servidor via a requisição Ajax disparada pelo cliente (recomendado na maioria dos casos).

Abaixo estão exemplos para ambas as abordagens.

1

Atualizando o cliente diretamente usando um manipulador de evento JavaScript

Você pode processar mensagens apenas no lado do cliente escrevendo um manipulador de evento JavaScript que altera elementos da interface Web com base nos parâmetros da mensagem. Isso requer conhecimento básico da API do Ext JS.

BroadcastMessage pode aceitar parâmetros também:

Delphi
procedure BroadcastMessage(const Msg: string; const Args: arrayofconst; ClientOnly: Boolean = False);

Exemplo enviando uma mensagem com parâmetros:

Delphi
BroadcastMessage('update_grid',
  [
    'row', IntToStr(Random(GRD_ROW) + 1),
    'col', IntToStr(Random(GRD_COL) + 1),
    'value', Random(1000)
  ],
  [boClientOnly]);

Os parâmetros são enviados ao cliente como um objeto JSON, por exemplo:

{ "row": "5", "col": "10", "value": 156 }

A boClientOnly a opção indica que o cliente deve processar a mensagem localmente e nenhuma requisição Ajax é disparada. Se boClientOnly for omitido, o cliente disparará uma requisição Ajax e a mensagem será processada no lado do servidor.

Exemplo de manipulador no lado do cliente:

JavaScript
function form.socketmessage(sender, msg, params, eOpts)
{
  if (msg == 'update_grid') {
    var row, col;
    var grd = MainForm.UniStringGrid1;
    for (prop in params) {
      var p = params[prop];
      if (prop == 'row') {
        row = grd.store.getAt(p);         // número da linha
      } elseif (prop == 'col') {
        col = p;                          // número da coluna
      } elseif (prop == 'value' && row && col) {
        row.set(col, p);
      }
    }
  }
}

O código acima atualiza uma grade no lado do cliente:

clip0242

Pasta de demonstração: ..\Desktop\WebSocket - Client Update Grid

circle-info

Vantagens das atualizações diretas no lado do cliente:

  • Atualiza rapidamente a interface do cliente via canal WebSocket sem usar os canais padrão Ajax/HTTP (reduz a carga nos canais HTTP). Desvantagens:

  • Requer escrever JavaScript (código do lado do cliente), que é mais limitado em comparação com atualizações do lado do servidor.

  • Todos os clientes recebem os mesmos dados; não há uma forma integrada de personalizar os dados por sessão.

2

Atualizando o cliente usando código do lado do servidor

Você também pode atualizar o cliente a partir de código do lado do servidor — essa abordagem frequentemente não requer JavaScript e é mais direta para muitas aplicações.

Quando BroadcastMessage é chamado ele envia a mensagem através do canal WebSocket para todos os clientes existentes. Dependendo do ClientOnly parâmetro o cliente web irá ou não enviar uma requisição Ajax de volta ao servidor. ClientOnly é falso por padrão, então uma requisição Ajax será enviada. A requisição Ajax informa ao servidor que o cliente solicita uma atualização; o código necessário do lado do servidor deve ser adicionado ao manipulador para atualizar a interface do cliente.

Nota: Este método requer uma requisição Ajax para cada mensagem WebSocket, o que pode acarretar penalidade de desempenho se houver muitas atualizações em curto intervalo de tempo. Isso pode ser mitigado pelas funcionalidades de escalabilidade do uniGUI, como usar um server farm onde a carga é balanceada.

Exemplo de uso em aplicação:

Delphi
BroadcastMessage('message', ['text', UniEdit1.Text]);

Como boClientOnly não está incluído, um evento do lado do servidor é executado:

Delphi
procedure TMainForm.UniFormBroadcastMessage(const Sender: TComponent;
  const Msg: string; const Params: TUniStrings);
begin
  if Msg = 'message' then
  begin
    ShowMessage(Params['text'].AsString);
  end;
end;

O manipulador de evento acima mostra a mensagem recebida:

clip0252

Como mostrado, processar a mensagem no lado do servidor é mais simples de implementar para muitos cenários, mas envolve overhead extra, já que a mensagem vai do servidor para o cliente e então retorna ao servidor.

chevron-rightPastas de demonstração referenciadashashtag
  • ..\Desktop\WebSocket - Client Update Grid

  • ..\Desktop\WebSocket - Basic