Este sistema de chat é escrito na linguagem Python e usa Sockets TCP na camada de transporte para realizar a comunicação no modelo cliente-servidor. O servidor suporta N clientes e a porta escolhida para comunicação é a 9999.
Content-length: int
{
"client_name": "str",
"subject": "str",
"message": "str",
"date": "str"
}'
O protocolo de mensagem é definido com um header Content-length finalizado por quebra de linha, na qual possui o tamanho (em bytes) da próxima mensagem que o cliente deve ler. Essa mensagem é codificada usando a notação JSON (JavaScript Object Notation). Essa escolha é feita pela robustez de poder enviar qualquer tipo de caractere no campo de mensagem. Se todos os atributos fossem finalizados com a quebra de linha, a mensagem em si não poderia ter quebra de linha, do contrário iria quebrar a aplicação.
Esse protocolo é definido no arquivo ./protocol.py na classe
Message
. O host
e porta
padrão também é definido nesse mesmo
arquivo, com os valores de 127.0.0.1 e 9999.
Os arquivos ./client.py e ./server.py contém ambos os códigos destinados ao cliente e servidor já integrado com a interface gráfica.
O sistema de concorrência é gerenciado usando filas e threads. O framework para criação de interfaces é o Qt, especificamente PyQt5.
Uma tela gráfica adicional é escrita em ./main.py para disparar N servidores e N clientes parametrizados por host e porta, a fim simplificando o teste. A comunicação entre todos servidores e clientes por esta tela continua sendo por Socket TCP com o protocol acima definido.
Quando o servidor é iniciado, ele terá duas threads principais: a da interface gráfica e outra thread de controle do Socket que ouve na porta 9999. Essa thread de controle do Socket esperará novos clientes se conectarem e para cada novo cliente conectado uma nova thread será disparada para esperar as mensagens desse novo cliente.
Todas as mensagens novas no servidor são salvas numa fila thread-safe, alimentadas em cada uma das threads de leitura de mensagens e consumida de forma sincronizada na interface gráfica. Adicionalmente, quando uma mensagem é consumida, é enviado uma espécie de broadcast para todos os clientes conectados. Dessa maneira os clientes também conseguirão receber mensagens de outros clientes.
Você deve possuir a versão 3.7 de Python instalado no sistema. As
dependências podem ser instaladas pelo gerenciador de pacotes do
python pip
. O seguinte comando deverá instalar o PyQt5, biblioteca
wrapper do framework Qt5 para criação de interfaces gráficas:
pip install -r requirements.txt
Para executar o sistema, primeiro rode o servidor via:
python server.py
Então execute depois quantos clientes quiser via:
python client.py
- http://pyqt.sourceforge.net/Docs/PyQt5/designer.html
- http://www.science.smith.edu/dftwiki/index.php/PyQt5_Simple_Example
- https://docs.python.org/3/howto/sockets.html
- https://docs.python.org/3/library/queue.html
- https://pythonspot.com/pyqt5-buttons/
- https://www.programcreek.com/python/example/108075/PyQt5.QtWidgets.QShortcut