Bonjour,
J'ai réalisé un tchat basique fonctionnant sur le protocole TCP/IP avec une architecture clients/serveur (en PyQt, mais ceci n'a pas d'importance ici).
Le client est composé d'un QTextEdit où j'affiche la conversation, d'un QListWidget qui affiche la liste des personnes connectés, et enfin d'un QLineEdit (et d'un bouton) pour envoyer les messages au serveur qui s'occupe de renvoyer le message à tout le monde.
Ca ressemble à ça :
Voici le code de mon serveur :
Comme vous pouvez le voir, j'utilise un message "spécial" pour indiquer aux clients la connexion ou la déconnexion d'une personne pour y afficher (ou retirer) son pseudo dans la QListWidget.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 # -*- coding: utf-8 -*- import sys, socket import threading class Server: def __init__(self, address): self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.bind(address) self.socket.listen(5) self.clients = [] self.pseudos = [] def wait_for_clients(self): while True: client, address = self.socket.accept() self.clients.append(client) t = ListeningThread(self.clients, client, self.pseudos) t.start() class ListeningThread(threading.Thread): def __init__(self, clients, client, pseudos): threading.Thread.__init__(self) self.clients = clients self.client = client self.pseudos = pseudos def run(self): name = self.client.recv(1024) print type(name) address = self.client.getsockname() message = "<font color='gray'><b>" + name + "</b> est connecté</font>" if len(self.pseudos) > 0: self.client.send("MAJsuperman " + str(','.join(self.pseudos))) self.send_to_all(message) self.pseudos.append(name) self.send_to_all("JOINsuperman " + name) while True: message = self.client.recv(1024) if message == "": self.clients.remove(self.client) message = "<font color='gray'><b>" + name + "</b> s'est déconnecté</font>" self.send_to_all("LEFTsuperman " + name) self.pseudos.remove(name) self.send_to_all(message) break message = "<b>" + name + "</b> : " + message self.send_to_all(message) def send_to_all(self, message): print message for client in self.clients: client.send(message) if len(sys.argv) != 3: print """Usage: python server.py ip port example: python server.py localhost 54321""" sys.exit() address = sys.argv[1], int(sys.argv[2]) server = Server(address) server.wait_for_clients()
Cependant, lorsque je fais appel à la méthode send_to_all 2 fois à la suite, du côté du client je ne reçois pas 2 messages séparément, mais je reçois un seul message avec les 2 messages concaténés...
Concrètement côté serveur j'envoie :
- "<font color='gray'><b>" + name + "</b> est connecté</font>" d'une part, et :
- "JOINsuperman " + name d'autre part
et côté client, au lieu de recevoir ces messages séparément afin d'afficher le premier message dans le QTextEdit, et de traiter le second message en affichant le pseudo dans la QListWidget, je reçois les 2 messages ensemble en une seule fois...
<font color='gray'><b>" + name + "</b> est connecté</font>JOINsuperman mon_pseudo
A noter que ceci est aléatoire, parfois ça fonctionne, et souvent ce phénomène ce produit... (seulement lors de la connexion/déconnexion vu que je fais plusieurs send() en suivant). Lors d'une discussion tout fonctionne bien.
Si besoin, voici la méthode côté client qui s'occupe de recevoir les messages et de les traiter en fonction :
Sauriez-vous comment je pourrais y remédier ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 def run(self): while self.running: message = self.sock.recv(1024) print 'message recu: ' + message if message[0:11] == "MAJsuperman": pseudos = message[12:] self.emit(SIGNAL("maj"), pseudos) elif message[0:12] != "JOINsuperman" and message[0:12] != "LEFTsuperman" and message[0:11] != "MAJsuperman": self.emit(SIGNAL("message_recu"), message) elif message[0:12] == "JOINsuperman": pseudo = message[13:] self.emit(SIGNAL("join"), pseudo) elif message[0:12] == "LEFTsuperman": pseudo = message[13:] self.emit(SIGNAL("left"), pseudo) QApplication.processEvents()
Merci d'avance !
Partager