Atualmente, estou tentando projetar a arquitetura de um novo jogo para celular MMORPG para minha empresa. Este jogo é semelhante ao Mafia Wars, iMobsters ou RISK. A idéia básica é preparar um exército para combater seus oponentes (usuários online).
Embora eu tenha trabalhado anteriormente em vários aplicativos móveis, isso é algo novo para mim. Depois de muita luta, criei uma arquitetura ilustrada com a ajuda de um fluxograma de alto nível:
Decidimos seguir com o modelo cliente-servidor. Haverá um banco de dados centralizado no servidor. Cada cliente terá seu próprio banco de dados local que permanecerá sincronizado com o servidor. Este banco de dados atua como um cache para armazenar coisas que não mudam frequentemente, como mapas, produtos, inventário etc.
Com esse modelo, não tenho certeza de como lidar com os seguintes problemas:
- Qual seria a melhor maneira de sincronizar bancos de dados de servidores e clientes?
- Um evento deve ser salvo no banco de dados local antes de atualizá-lo no servidor? E se o aplicativo terminar por algum motivo antes de salvar as alterações no banco de dados centralizado?
- Solicitações HTTP simples servirão ao propósito de sincronização?
- Como saber quais usuários estão conectados no momento? (Uma maneira seria manter o cliente enviando uma solicitação ao servidor após cada x minutos para notificar que está ativo. Caso contrário, considere um cliente inativo).
- As validações do lado do cliente são suficientes? Caso contrário, como reverter uma ação se o servidor não validar algo?
Não tenho certeza se esta é uma solução eficiente e como será dimensionada. Eu realmente aprecio se as pessoas que já trabalharam nesses aplicativos puderem compartilhar suas experiências, o que pode me ajudar a encontrar algo melhor. Desde já, obrigado.
Informação adicional:
O lado do cliente é implementado no mecanismo de jogos C ++ chamado marmelada. Esse é um mecanismo de jogo de plataforma cruzada, o que significa que você pode executar seu aplicativo em todos os principais SOs móveis. Certamente, podemos realizar rosqueamento, o que também é ilustrado no meu diagrama de fluxo. Estou planejando usar o MySQL para servidor e SQLite para cliente.
Este não é um jogo baseado em turnos, portanto não há muita interação com outros jogadores. O servidor fornecerá uma lista de jogadores on-line e você poderá batalhá-los clicando no botão de batalha e, após alguma animação, o resultado será anunciado.
Para sincronização de banco de dados, tenho duas soluções em mente:
- Armazene o registro de data e hora para cada registro. Além disso, acompanhe quando o banco de dados local foi atualizado pela última vez. Ao sincronizar, selecione apenas as linhas que possuem um carimbo de data / hora maior e envie para o banco de dados local. Mantenha um sinalizador isDeleted para linhas excluídas, para que cada exclusão simplesmente se comporte como uma atualização. Mas tenho sérias dúvidas sobre o desempenho, pois, para cada solicitação de sincronização, teríamos que verificar o banco de dados completo e procurar linhas atualizadas.
- Outra técnica pode ser manter um log de cada inserção ou atualização que ocorra com um usuário. Quando o aplicativo cliente solicitar sincronização, vá para esta tabela e descubra quais linhas de qual tabela foram atualizadas ou inseridas. Depois que essas linhas forem transferidas com sucesso para o cliente, remova esse log. Mas então penso no que acontece se um usuário usa outro dispositivo. De acordo com a tabela de logs, todas as atualizações foram transferidas para esse usuário, mas na verdade isso foi feito em outro dispositivo. Portanto, talvez tenhamos que acompanhar o dispositivo também. A implementação dessa técnica consome mais tempo, mas não tem certeza se ela executa a primeira.