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 | #/usr/bin/python # -*- coding:utf-8 -*- from twisted.internet.protocol import Factory from twisted.protocols.basic import LineReceiver from twisted.internet import reactor class Chat(LineReceiver): #定义一个新的协议,这里继承的是LineReceiver,这个协议在protocol的上层,因为继承protocol #和另外的一些底层协议 def __init__( self , users): #初始化3个变量,users做为形参传递,也就是我们下面需要传入的名字 self .users = users self .name = None self .state = "newone" #定义名字的状态,这里先定义为"新来的",因为没一个新的连接都需要初始化。 def connectionMade( self ): #连接协议,当客户端连接即发出消息 self .sendLine( "What's your name?" ) def connectionLost( self , reason): #定义客户端断开连接的函数 if self .name in self .users: #判断下名字是否存在于字典中,有则删除 del self .users[ self .name] #"这里没有定义如何断开连接,所以按CTRL+C也不好使" def lineReceived( self , line): #定义接收消息的函数 if self .state = = "newone" : #如果这个用户的状态是前面定义的newone self .handle_newone(line) #就调用handle_newone函数,这个函数就是处理新用户的,包括取名啊什么的 else : self .handle_CHAT(line) #否则就调用chat函数,这个函数就是负责聊天,传递消息的 def handle_newone( self , name): #上述的处理"新来的"函数 if name in self .users: #名字重复了,另外再取吧,所以啊 定义一个自己喜欢的名字真的很难 self .sendLine( "Name taken, please choose another." ) return #直接返回 +.+ self .sendLine( "Welcome, %s!" % (name,)) #没有重复,当你输入名字以后,传递消息给你,欢迎你 self .name = name #这里重写了3个变量, self .users[name] = self #存字典,你懂的,self这里表示的是类本身,就是这个name在这个类中的位置,存放在什么位置,具体也说不清 self .state = "CHAT" #改变这个"新来的"状态为CHAT,去聊天吧 def handle_CHAT( self , message): #聊天的函数,message作为形参传递 message = "<%s> %s" % ( self .name, message) #定义一个变量,没啥好说的 for name, protocol in self .users.iteritems(): #这里是重点,我们从字典里去取用户名和他在这个类中的位置, if protocol ! = self : #位置判断了这2个到底是不是一个用户,如果是的话什么都不干,不是就传送消息. protocol.sendLine(message) class ChatFactory(Factory): #没工厂上面的东西没法加工 def __init__( self ): self .users = {} #这里定义了字典,self.users。上面用的 def buildProtocol( self , addr): #回调自己定义的协议 return Chat( self .users) reactor.listenTCP( 8123 , ChatFactory()) #绑定端口和工厂,开始加工了。。。。 reactor.run() #启动事件循环。 综上看来twisted实现一个简单的聊天室 还是很容易的 |
联系客服