2017-08-22 1 views
0

J'écris un serveur de chat dans Twisted et j'ai un problème dans la compréhension broacastMessage() Méthode:broadcastMessage dans le serveur de chat Twisted

def broadcastMessage(self, message): 
    print list(self.factory.users.iteritems()) 

    for name, protocol in self.factory.users.iteritems(): 
     if protocol != self: 
      protocol.sendLine(message) 

Je sais iteritems() devrait donner un tuple, par exemple ('Roman', <__main__.ChatProtocol instance at 0x7fc80b8b67a0>). Maintenant, en itérant à travers ce tuple names et protocols nous comparons ce s'il ne s'agit pas d'une instance self, simplement parce que nous ne voulons pas imprimer un message pour l'utilisateur qui l'a envoyé? (Ai-je obtenir ce droit?)

Attendez-vous à ce que cela fonctionne mais pas pour une raison quelconque. Voici le code :

from twisted.internet import protocol, reactor 
from twisted.protocols.basic import LineReceiver 

class ChatProtocol(LineReceiver): 
    def __init__(self, factory): 
     self.factory = factory 
     self.name = None 
     self.state = "REGISTER" 

    def connectionMade(self): 
     self.sendLine("What's your name?") 

    def connectionLost(self, reason): 
     if self.name in self.factory.users: 
      del self.factory.users[self.name] 
      self.broadcastMessage("%s has left the channel." % (self.name,)) 

    def lineReceived(self, line): 
     if self.state == "REGISTER": 
      self.handle_REGISTER(line) 
     else: 
      self.handle_CHAT(line) 

    def handle_REGISTER(self, name): 
     if name in self.factory.users: 
      self.sendLine("Name taken, please choose another.") 
      return 
     self.sendLine("Welcome, %s!" % (name,)) 
     self.broadcastMessage("%s has joined the channel." % (name,)) 
     self.name = name 
     self.factory.users[name] = self 
     self.state = "CHAT" 

    def handle_CHAT(self, message): 
     message = "<%s> %s" % (self.name, message) 
     self.broadcastMessage(message) 

    def broadcastMessage(self, message): 
     for name, protocol in self.factory.users.iteritems(): 
      if protocol != self: 
       protocol.sendLine(message) 

class ChatFactory(protocol.Factory): 
    def __init__(self): 
     self.users = {} 

    def buildProtocol(self, addr): 
     return ChatProtocol(self) 

reactor.listenTCP(8000, ChatFactory()) 
reactor.run() 

Et voici la session de terminal :

(venv) [email protected] ~/Documents/learning/twisted/chat_server $ telnet localhost 8000 
Trying ::1... 
Trying 127.0.0.1... 
Connected to localhost. 
Escape character is '^]'. 
What's your name? 
Roman 
Welcome, Roman! 

P.S .: J'utilise Telnet pour envoyer des messages.

Répondre

0

Etes-vous sûr que cela ne fonctionne pas? Il semble que cela fonctionne pour moi, à la fois en fonction de la transcription de votre session de terminal et des tests locaux.

Dans votre transcription de session, vous avez entré le nom "Roman" et reçu la réponse "Bienvenue, Roman!". Cela est dû à la ligne:

self.sendLine("Welcome, %s!" % (name,)) 

Une connexion différente au même serveur reçoit le message "Roman a rejoint le canal". en raison de la ligne:

self.broadcastMessage("%s has joined the channel." % (name,)) 

En outre, l'appel broadcastMessage n'a pas pu envoyer le message « joint » à l'utilisateur qui a rejoint car au point de son appel, l'utilisateur « joint » n'a pas encore été ajouté à la usine users dict.