I’m struggling to have a message delivered from a user to another one connected in the same net by Websocket. The connection between both of them is well suceeded but as I try to send the message it doesn’t reaches the destination. It’s is probably something related to the non-existence of chat threads or the use of callback functions that I don’t dominate.
Chat_Thread.py (only important parts):
async def talk(self):
self.interface = Interface(self.cliente.nome, send_callback=self.send_message)
self.interface.print("Você está conversando com " + self.cliente.nome)
async for message in self.socket:
print(f"Recebendo mensagem: {message}")
self.interface.print(f"[{self.cliente.nome}]: {message}")
async def send_message(self, message):
if self.socket:
print(f"Enviando mensagem: {message}")
await self.socket.send(message)
self.interface.print(f"Você: {message}")
else:
print(f"DEU MERDA")
conexao_socket.py (only important parts):
async def websocket_handler(websocket: websockets.server.WebSocketServerProtocol, path: str) -> None:
client_name: str = websocket.request_headers.get("client-name")
nome_valido = validar_nome_cliente(client_name)
try:
if not nome_valido: await send_error(websocket, "Nome inválido")
message = await websocket.recv()
print(f"(websocket_handler) Mensagem recebida: {message}")
if message != MensagemSocket.SOLICITAR_CONEXAO.value: await websocket.send(json.dumps({"error": "Mensagem inválida"}))
thread_aberta = shared.chat_threads.get(client_name)
if thread_aberta is not None: await send_error(websocket, "Conexão já solicitada ou ativa")
print(f"Conexão solicitada por {client_name}")
except websockets.exceptions.InvalidMessage: return
shared.chat_threads[client_name] = Chat_Thread(
Cliente(client_name, websocket.remote_address),
StatusChat.SOLICITACAO_PENDENTE,
socket = websocket,
)
print(f"Chat_Thread criado para {client_name}")
await websocket.wait_closed()
interface.py(only important parts):
def send_message(self):
message = self.entry.get()
print(f"(interface.send_messge) mensagem: {message}")
if message and self.send_callback:
# Use run_coroutine_threadsafe to ensure the coroutine runs in the event loop
print(f"Vai executar asyncio.ensure_future")
asyncio.ensure_future(self.send_callback(message), loop=self.loop)
self.print(f"executou asyncio.ensure_future Você: {message}") # Display the message locally
self.entry.delete(0, tk.END)
main.py
import asyncio
import shared
from validacao import validar_nome_cliente
from websockets.server import WebSocketServerProtocol, WebSocketServer, serve
import socket as EnumSocketFamily
from server_handler import me_registrar
from graceful_exit import GracefulExit
from menu import exibir_menu
from sys import argv
from random import choices, choice
from string import ascii_lowercase, digits
from conexao_socket import websocket_handler, inicializar_socket_headers
from cliente import Cliente
get_client_host = lambda: 'localhost'
def criar_nome_cliente():
if len(argv) <= 1 or not validar_nome_cliente(argv[1]):
identifier = ''.join(choices(ascii_lowercase, k=4))
print(f"Nome não inserido ou inválido, seu nome será {identifier}")
return identifier
else:
return argv[1]
def criar_url(server: WebSocketServer):
sock = server.sockets[0]
if sock.family == EnumSocketFamily.AF_INET:
return "%s:%d" % sock.getsockname()
elif sock.family == EnumSocketFamily.AF_INET6:
return "[%s]:%d" % sock.getsockname()[:2]
elif sock.family == EnumSocketFamily.AF_UNIX:
return sock.getsockname()
else:
return str(sock.getsockname())
def criar_cliente(server: WebSocketServer):
shared.me = Cliente(criar_nome_cliente(), criar_url(server))
print(f"Seja bem vindo, {shared.me.nome}!")
async def start_ws_server():
server = await serve(websocket_handler, get_client_host(), 0)
criar_cliente(server)
me_registrar()
inicializar_socket_headers()
print(f"WebSocket server running at {shared.me.endereco}")
menu_task = asyncio.create_task(exibir_menu())
try:
await asyncio.Future()
except GracefulExit:
print("Received exit signal, shutting down...")
finally:
menu_task.cancel()
server.close()
await server.wait_closed()
print("WebSocket server stopped")
if __name__ == "__main__":
asyncio.run(start_ws_server())
As I hit send button nothing reaches the destination, the message only appears for the sender.
send_message from Chat_Thread.py is never used, this might be a problem.
Don’t worry about connecting the users this is working fine and the chat interfaces are loading for both