A proposta desta atividade foi a criação de um cliente que tivesse a capacidade de se conectar com o webservice do WorldServer3D com capacidade de comunicação com o mesmo.
A principal dificuldade se encontrou no fato da percepção de que o WorldServer3D continua rodando em background se for fechado pelo 'x' da janela do sistema operacional em vez de se utilizar o menu da aplicação para tal. Este comportamento faz com que o cliente consiga se conectar apenas no primeiro WorldServer3D inicializado, fazendo com que os comandos não fossem enviados fossem para o servidor esperado. Obviamente, o último servidor iniciado, onde se esperava observar o resultado dos comandos, jamais recebia as mensagens do cliente.
Superada esta dificuldade, foi criado um cliente com capacidade de enviar mensagens genéricas para o servidor e que constantemente ouve mensagens enviadas por este e imprime em um campo de texto da interface. Com estas capacidades implementadas, só se fez necessário compreender o formato de cada comando e utilizar eventos de teclado para identificar inputs do usuário, criar a mensagem correspondente e enviá-la ao servidor.
Abaixo, a imagem da interface do cliente desenvolvido
O usuário deve fornecer o servidor e a porta onde se encontra o WebService3D e clicar em conectar. Se a conexão for bem sucedida, os botões para iniciar a criatura (Start Creature), iniciar o jogo (Start Game) e os botões da barra de ferramentas lateral (em ordem: adicionar criatura, refrescar criatura e remover criatura) ficarão habilitados.
Os comandos para iniciar, criar, refrescar e remover uma criatura, assim como os comandos evniados pelo input do teclado, se relacionam sempre com a criatura de ID indicado na caixa Creature ID.
Idealmente o cliente deveria ser stateless no que diz respeito à informações da criatura manipulada (as informações a respeito de Wheel, VR e VL deveriam exibir uma informação enviada pelo servidor e não manter nenhum estado para elas em sua memória). Contudo, por limitações nas respostas que o servidor envia não foi possível implementar este comportamento. Com poucas mudanças no formato das respostas que o servidor envia ao cliente, poderíamos interpretar o estado do servidor e exibir na interface. Foi necessário manter estas informações para promover atualização do estado da criatura quando um comando do teclado fosse enviado. Por exemplo, quando a tecla W é pressionada, o cliente comanda que o servidor atualize a velocidade da criatura para a velocidade atual mais um diferencial. Se a mudança proposta fosse feita ao servidor poderíamos primeiro descobrir qual a velocidade atual da criatura e em seguida enviar uma mensagem com este valor incrementado do diferencial. Outra maneira, seria criar no servidor um método para tratar mensagens de incremento de velocidade: em vez de dizer qual deve ser a velocidade da criatura, informaríamos qual o incremento que a criatura deve ter em sua velocidade atual. Isto é especialmente útil para evitar cenários de concorrência de comandos.
O fluxo básico de tratamento de inputs, sejam eles provenientes do teclado ou do clique em botões é:
- Identificar o input
- Criar uma mensagem formatada especialmente para o tipo de input recebido, dado o estado atual da simulação
- Envio da mensagem para o servidor através do socket
Seria possível efetuar algumas melhorias no comportamento do cliente. Dentre elas se destacam:
- Constante verificação da saúde da conexão e tratamento de possíveis falhas
- Modificação da lógica de alteração da velocidade da criatura para que esta desacerele gradualmente se as teclas de movimento forem soltas
- Tratamento do caso de alteração da criatura selecionada (CreatureID), para resetar os valores do estado da criatura em memória para os valores da nova criatura selecionada
- Tornar o cliente stateless como descrito anteriormente, alterando a mensagem enviada pelo servidor para um formato mais amigável como JSON ou interpretar a mensagem enviada atualmente, que se encontra sem um formato amigável para a tarefa.
Com exceção da primeira, estas mudanças não foram implementadas por fugirem do escopo da tarefa proposta e especialmente porque para tarefas futuras que utilizaram este cliente, estas mudanças seriam inúteis.
No mais, o cliente se comporta de maneira satisfatória sem problemas de performance ou alocação excessiva de memória.
Clique para iniciar o WorldServer3D e o Cliente.
Vale lembrar que o servidor está configurado para rodar na porta 4012.
O código fonte do aplicativo cliente se encontra aqui.