Dicas ABAP

Published on January 3rd, 2018 | by Leo Schmidt

1

Chat Zumbizade™ com ABAP Channels e UI5

Fala zumbizada!

Saindo da tumba após eras de profundo adormecimento, cá estou eu de volta à linha de frente zumbi pra despejar um pouco mais de conhecimento para nós, seres meio-viventes. Dessa vez, vim pra mostrar um exemplo lúdico de algo que comentei no último episódio do nosso cast (que sim, saiu ano passado, porém não se desesperem pois novos episódios estão a caminho- sim, com S): uma aplicaçãozinha chat feita com ABAP Channel e UI5.

Pra quem não sabe, ABAP Channel é a implementação ABAP de web sockets. Se você não entende patavinas deste assunto, recomendo fortemente a leitura do post da SAP Community (é assim que chama agora né?) que eu indiquei no The Walking Dev #008 (eis o link outra vez). Web sockets são coisas bem interessantes, que tem ótimas possibilidades de aplicação dentro do SAP, como por exemplo para a criação de dashboards real-time, clientes de workflow, ferramentas de cooperação, etc.

A ideia desse exemplo é construir um chat simples com uma sala única pra todos os usuários logados em um mesmo sistema. Cada usuário entra com o próprio ID na sala e um avatar escolhido aleatoriamente dentre os ícones disponíveis no UI5. As mensagens são exibidas com o timestamp gerado pelo servidor.

Maurício fala reservadamente para todos: oi e vc

Vamos aos objetos:

Push channel

Esse nome de classe escroto foi gerado automaticamente blz?

Aqui não tem nada de complicado, basta dar um nome pra sua aplicação e uma descrição e clicar ali em Generate Class and Service. Salvar e ativar, como sempre.

Message channel

Dei o mesmo nome pro message channel por motivos de preguiça

message channel também é bem simples: só tem um canal, /chat, que vai ser do tipo TEXT e com escopo S (System). Aí adicionamos a classe gerada pro push channel na lista de programas autorizados para as atividades C (receber dados por push channel) e S (enviar). Novamente, salvar e ativar.

Implementação da classe

Private section

Aqui temos um tipo pra criar uma tabela de usuários conectados no chat, e a declaração do método que vai ser usado para enviar mensagens.

IF_APC_WSP_EXTENSION~ON_START

Esse método é chamado assim que a conexão do web socket é iniciada.

Na primeira parte, fazemos o binding do push channel com o message channel, criando duas extensões diferentes: /users, onde vão trafegar as mensagens sobre conexão e desconexão de usuários, e /messages, onde vão trafegar as mensagens do chat em si. Esse recurso das extensões é muito bacana, porque permite segmentar as mensagens sem ter que criar canais diferentes na mesma aplicação.

Quando a conexão é criada, a aplicação UI5 vai chamar o serviço passando um parâmetro de URL chamado avatar, que vai conter o ID do avatar gerado aleatoriamente pelo frontend (porque é lá que fica a coleção de ícones). Juntamos esse valor com o nome do usuário e gravamos a tabela toda num cluster na INDX (tomando cuidado pra ver se o usuário já está logado). Achei mais simples usar EXPORT ... TO DATABASE nesse caso, mas num caso normal talvez seria melhor usar shared memory.

Por fim, enviamos na extensão /users uma mensagem com a tabela atualizada de usuários conectados.

IF_APC_WSP_EXTENSION~ON_MESSAGE

Esse método é chamado toda vez que o push channel recebe uma mensagem – no nosso caso, é sempre uma mensagem do chat. Portanto, é uma implementação bem simples: pegamos o texto, marcamos com o ID do usuário e o timestamp formatado como ISO no fuso local, e retornamos na extensão /messages.

IF_APC_WSP_EXTENSION~ON_CLOSE

Esse método é chamado ao encerrar a conexão. Aqui, precisamos notificar todos que houve uma desconexão, então verificamos a tabela de usuários e removemos o ID que desconectou, tomando o cuidado de zerar a tabela do cluster na INDX quando não houver mais ninguém no chat. A tabela final é enviada na extensão /users.

SEND_MESSAGE

Esse é um método utilitário para enviar mensagens pelo message channel. Basicamente, pegamos os dados que precisam ser enviados (em qualquer formato que estejam: variável simples, estrutura, tabela, etc.), chamamos o CALL TRANSFORMATION id para gerar uma saída JSON através da CL_SXML_STRING_WRITER, e através de uma expressão regular deixamos todos os identificadores do JSON em minúsculas.

Por fim, criamos um message producer com a extensão necessária e enviamos a mensagem.

UI5

Chat.view.xml

Chat.controller.js

Tanto a view quanto o controller são bem simples.

view consiste em uma página com o conteúdo principal vazio, que é onde vão aparecer as mensagens assim que elas forem recebidas. O conteúdo fixo são duas toolbars, uma no topo com um tokenizer para exibir os usuários conectados e outra na parte de baixo com o input e o botão para enviar mensagens.

controller tem as seguintes atribuições:

  • Criar um JSONModel para alimentar o tokenizer (feito diretamente no onInit);
  • Definir o scroll automático da página, para quando novas mensagens forem adicionadas (método _setChatWindowScroll);
  • Impedir o uso de [Tab] no input, para que somente o [Enter] envie mensagens (método _setMessageInputKeydown);
  • Configurar o web socket (finalmente! pelo método _setWebSocket), onde:
    • Define-se um avatar aleatório, pelo índice do IconPool;
    • Abre-se a conexão com o web socket;
    • Define-se um event handler para quando chegarem mensagens:
      • Se houver o identificador connectedUsers, definir o conteúdo dentro do JSONModel;
      • Se houver o identificador message, criar um novo FeedListItem com os dados da mensagem;
  • Enviar a mensagem (método onSend);
  • E fechar a conexão com o web socket (diretamente no método onExit).

E é basicamente isso. Agora, caro amigo zumbi, vc tem um chat pra conversar com os seus outros amiguinhos zumbis no projeto.

Nas versões mais novas do UI5 já existe a classe sap.ui.core.ws.WebSocket, então se você estiver surfando na crista da onda já dá pra usar ela em vez da classe JS pura que eu usei aqui.

Dúvidas, sugestões ou comentários? Só postar que a gente se fala.

PS.: Nada disso está no Github por motivos de preguiça 🙁 Mentira! Tá lá no Github sim 🙂

Tags: , ,


About the Author

ABAP profissional desde dez/2008. Meu negócio é desenvolver ABAP, mas sem pensar só em ABAP: gosto de fazer o SAP conversar com outras linguagens e sistemas, sempre de olho no Basis.



One Response to Chat Zumbizade™ com ABAP Channels e UI5

  1. Richard says:

    Legal ver novos posts por aqui!

    No aguardo do podcast 😀

Leave a Reply

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

Back to Top ↑