Sistema Distribuído Simples para Manutenção de Contas Bancárias, utilizando arquitetura cliente-servidor, com comunicação via sockets TCP/IP.
- Login
- Consulta de Saldo
- Saque
- Depósito
- Transferência
- Python >= 3.8
- Iniciar o servidor:
PYTHONPATH=$(pwd) python3.8 pixson/servidor.py
Por padrão, o servidor irá iniciar na porta 5000.
- Iniciar o cliente:
PYTHONPATH=$(pwd) python3.8 pixson/cliente.py
Por padrão, o cliente irá iniciar se conectando ao servidor com o host localhost
e porta 5000
.
Cada conexão TCP/IP com os clientes é tratada em uma thread separada, para permitir que o servidor atenda múltiplos clientes simultaneamente.
O servidor é responsável por gerir as contas bancárias e as operações realizadas por elas. Para isso, ele mantém cada conta num arquivo JSON, com o nome do arquivo sendo o número no RG do usuário.
O acesso a esses arquivos é feito de forma concorrente, utilizando o módulo threading.Lock
para garantir que apenas uma thread tenha acesso ao arquivo por vez.
Exemplo de arquivo de conta:
{
"nome": "João da Silva",
"rg": "123456789",
"saldo": 1000.0
}
Já existem alguns arquivos de exemplo no diretório contas/
que podem ser utilizados para testes.
O cliente é responsável por enviar as requisições ao servidor e receber as respostas. Para isso, ele utiliza o módulo socket
para se conectar ao servidor e enviar as requisições.
A comunicação entre o cliente e o servidor é por mensagens de texto, cada uma representando uma operação. As classes que representam as mensagens estão no módulo pixson.recursos.protocolo
, onde cada classe representa uma mensagem.
Exemplo de mensagem de solicitação de transferência de 10.5 da conta 123456789 para a 987654321, no tempo lógico 10:
t:10|op:4|rg_origem:1111111111|rg_destino:987654321|valor:10.5
Foi implementado um relógio lógico, baseado no algoritmo de Lamport, para identificar a ordem das operações. O cliente e servidor iniciam com o relógio lógico zerado, e cada operação incrementa o relógio lógico em 1.
Todas as mensagens enviadas pelo cliente e servidor possuem um carimbo com o valor do relógio lógico atualizado. Quando uma nova mensagem é recebida, o relógio lógico do receptor é atualizado para o maior valor entre o relógio lógico e o carimbo da mensagem recebida.
Para todos os exemplos a seguir, o servidor e cliente já devem estar em execução.
$ PYTHONPATH=$(pwd) python3.8 pixson/servidor.py
Servidor iniciado na porta 5000
Aguardando conexão
$ PYTHONPATH=$(pwd) python3.8 pixson/cliente.py
Cliente iniciado
Realizar login com o RG 1111111111
Digite o RG associado a conta: 1111111111
Conectado ao servidor
Relógio Lógico Atualizado: 1
Relógio Lógico Atualizado: 4
Login realizado com sucesso
Consultar saldo, digitando a opção 1
1 - SALDO
2 - SAQUE
3 - DEPOSITO
4 - TRANSFERENCIA
0 - SAIR
Digite o comando: 1
Relógio Lógico Atualizado: 5
Relógio Lógico Atualizado: 8
Saldo: 10.0
Realizar saque, digitando a opção 2 e informando o valor 8.50
1 - SALDO
2 - SAQUE
3 - DEPOSITO
4 - TRANSFERENCIA
0 - SAIR
Digite o comando: 2
Digite o valor do saque: 8.50
Relógio Lógico Atualizado: 9
Relógio Lógico Atualizado: 12
Saque realizado com sucesso
Realizar depósito, digitando a opção 3 e informando o valor 14
1 - SALDO
2 - SAQUE
3 - DEPOSITO
4 - TRANSFERENCIA
0 - SAIR
Digite o comando: 3
Digite o valor do deposito: 14
Relógio Lógico Atualizado: 13
Relógio Lógico Atualizado: 16
Depósito realizado com sucesso
Realizar transferência, digitando a opção 4 e informando o RG 2222222222 da conta de destino e o valor 5.5
1 - SALDO
2 - SAQUE
3 - DEPOSITO
4 - TRANSFERENCIA
0 - SAIR
Digite o comando: 4
Digite o RG do destinatário: 2222222222
Digite o valor da transferência: 5.5
Relógio Lógico Atualizado: 17
Relógio Lógico Atualizado: 20
Transferência realizada com sucesso