Twisted使用了更多的基于事件的方式。要写一个基本的服务器,你要实现事件处理器,它处理诸如一个新的客户端连接、新的数据到达和客户端连接中断等情况。在Twisted中,你的事件处理器定义在一个protocol中;你也需要一个factory,当一个新的连接到达时它能够构造这个protocol对象,但是如果你仅仅想创建一个自定义的Protocol类的实例的话,你可以使用来自Twisted的factory,Factory类在模块twisted.internet.protocol中。当你写你的protocol时,使用twisted.internet.protocol模块中的Protocol作为你的父类。当你得到一个连接时,事件处理器 connectionMade被调用;当你丢失了一个连接时,connectionLost被调用。从客户端接受数据使用处理器 dataReceived。但是你不能使用事件处理策略向客户端发送数据;要向客户端发送数据,你可以使用self.transport,它有一个 write方法。它也有一个client属性,其中包含了客户端的地址(主机名和端口)。
下面这个例子是一个Twisted版的服务器。其中实例化了Factory并设置了它的protocol属性以便它知道使用哪个protocol与客户端通信(这就是所谓的你的自定义 protocol)。然后你使用factory开始监听指定的端口,factory通过实例化的protocol对象处理连接。监听使用reactor模块中的listenTCP函数。最后,你通过调用reactor模块中的run函数来开始服务器。
- from twisted.internet import reactor
- from twisted.internet.protocol import Protocol, Factory
- # 定义你Protocol类
- class SimpleLogger(Protocol):
- def connectionMade(self):
- print 'Got connection from', self.transport.client
- def connectionLost(self, reason):
- print self.transport.client, 'disconnected'
- def dataReceived(self, data):
- print data
- # 实例化Factory
- factory = Factory()
- # 设置factory的protocol属性以便它知道使用哪个protocol与客户端通信(这就是所谓的你的自定义
- # protocol)
- factory.protocol = SimpleLogger
- # 监听指定的端口
- reactor.listenTCP(1234, factory)
- # 开始运行主程序
- reactor.run()
为你的处理目的而写一个自定义的protocol是很容易的。模块twisted.protocols.basic中包含了几个有用的已存在的 protocol,其中的LineReceiver执行dataReceived并在接受到了一个完整的行时调用事件处理器lineReceived。如果当你在接受数据时除了使用lineReceived,还要做些别的,那么你可以使用LineReceiver定义的名为rawDataReceived 事件处理器。下面是一使用LineReceiver的服务器例子:
- from twisted.internet import reactor
- from twisted.internet.protocol import Factory
- from twisted.protocols.basic import LineReceiver
- class SimpleLogger(LineReceiver):
- def connectionMade(self):
- print 'Got connection from', self.transport.client
- def connectionLost(self, reason):
- print self.transport.client, 'disconnected'
- def lineReceived(self, line):
- print line
- factory = Factory()
- factory.protocol = SimpleLogger
- reactor.listenTCP(1234, factory)
- reactor.run()
参考来自:
http://acen-chen.javaeye.com/blog/290179
http://twistedmatrix.com/projects/core/documentation/howto/clients.html
============================================================== 以下代码与上面无关
//部分二: 一个server实例
- # -*- coding: UTF-8 -*-
- #Twisted MMORPG
- from twisted.internet.protocol import Factory
- from twisted.protocols.basic import LineOnlyReceiver
- from twisted.internet import reactor
- import random
- import string
- class Game(LineOnlyReceiver):
- def lineReceived(self, data):
- self.factory.sendAll("%s" % (data))
-
- def getId(self):
- return str(self.transport.getPeer())
-
- def connectionMade(self):
- print "New User Login:", self.getId()
- self.transport.write("欢迎来到MMO世界!\n")
- self.factory.addClient(self)
-
- def connectionLost(self, reason):
- self.factory.delClient(self)
-
- class GameFactory(Factory):
- protocol = Game
- def __init__(self):
- self.clients = []
- self.player = []
- self.msg=''
- self.x = range(100,700)
- self.y = range(100,500)
-
- def getPlayerId(self):
- return len(self.player)
-
- def addClient(self, newclient):
- self.clients.append(newclient)
-
- def delClient(self, client):
- self.clients.remove(client)
-
- def sendAll(self, data):
- #print data
- if data.find('')!=-1:
- proto.transport.write('\0')
- else:
- arr = data.split(':')
- prefix = arr[0]
- content = arr[1]
- if prefix.find('player')!=-1:
- newPlayer = [content,str(random.randrange(200, 600)),str(random.randrange(150,350)),str(random.randrange(1,5))]
- self.player.append(newPlayer)
- self.msg = ' 玩家 '+content+' 进入游戏!'
- #广播所有玩家的位置
- temp = []
- playerData = ':::'
- for pos in self.player:
- temp.append(string.join(pos,'---'))
-
- playerData = playerData+string.join(temp,'***')
- for proto in self.clients:
- proto.transport.write('[系统]: '+self.msg+'\n')
- proto.transport.write(playerData)
- elif prefix.find('pos')!=-1:
- playerName,x,y = content.split('---')
- i = 0
- for p in self.player:
- if p[0]==playerName:
- p[1]=x
- p[2]=y
- for proto in self.clients:
- proto.transport.write(data)
- else:
- self.msg = data
- for proto in self.clients:
- proto.transport.write(self.msg+'\n')
-
- reactor.listenTCP(8006, GameFactory())
- reactor.run()
// 部分三一个client例子,与前文不相关
- from twisted.internet.protocol import ClientCreator, Protocol
- from twisted.protocols.basic import LineReceiver
- from twisted.internet import reactor
- import sys
- class Sender(Protocol):
- def sendCommand(self, command):
- print "invio", command
- self.transport.write(command)
-
- def dataReceived(self, data):
- print "DATA", data
-
- PORT = 5005
- HOST = 'localhost'
- def sendCommand(command):
- def test(d):
- print "Invio ->", command
- d.sendCommand(command)
-
- c = ClientCreator(reactor, Sender)
- c.connectTCP(HOST, PORT).addCallback(test)
- if __name__ == '__main__':
- if len(sys.argv) != 2 or sys.argv[1] not in ['stop', 'next_call', 'force']:
- sys.stderr.write('Usage: %s: {stop|next_call|force}\n' % sys.argv[0])
- sys.exit(1)
- sendCommand(sys.argv[1]+'\n')
- reactor.run()
阅读(1718) | 评论(0) | 转发(0) |