Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5120223
  • 博文数量: 921
  • 博客积分: 16037
  • 博客等级: 上将
  • 技术积分: 8469
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-05 02:08
文章分类

全部博文(921)

文章存档

2020年(1)

2019年(3)

2018年(3)

2017年(6)

2016年(47)

2015年(72)

2014年(25)

2013年(72)

2012年(125)

2011年(182)

2010年(42)

2009年(14)

2008年(85)

2007年(89)

2006年(155)

分类: Python/Ruby

2011-10-30 19:14:11

 
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函数来开始服务器。

  1. from twisted.internet import reactor
  2. from twisted.internet.protocol import Protocol, Factory

  3. # 定义你Protocol类
  4. class SimpleLogger(Protocol):

  5.     def connectionMade(self):
  6.         print 'Got connection from', self.transport.client
  7.     def connectionLost(self, reason):
  8.         print self.transport.client, 'disconnected'
  9.     def dataReceived(self, data):
  10.         print data


  11. # 实例化Factory

  12. factory = Factory()

  13. # 设置factory的protocol属性以便它知道使用哪个protocol与客户端通信(这就是所谓的你的自定义
  14. # protocol)

  15. factory.protocol = SimpleLogger

  16. # 监听指定的端口

  17. reactor.listenTCP(1234, factory)

  18. # 开始运行主程序
  19. reactor.run()

为你的处理目的而写一个自定义的protocol是很容易的。模块twisted.protocols.basic中包含了几个有用的已存在的 protocol,其中的LineReceiver执行dataReceived并在接受到了一个完整的行时调用事件处理器lineReceived。如果当你在接受数据时除了使用lineReceived,还要做些别的,那么你可以使用LineReceiver定义的名为rawDataReceived 事件处理器。下面是一使用LineReceiver的服务器例子:

  1. from twisted.internet import reactor
  2. from twisted.internet.protocol import Factory
  3. from twisted.protocols.basic import LineReceiver

  4. class SimpleLogger(LineReceiver):

  5.     def connectionMade(self):
  6.         print 'Got connection from', self.transport.client
  7.     def connectionLost(self, reason):
  8.         print self.transport.client, 'disconnected'
  9.     def lineReceived(self, line):
  10.         print line

  11. factory = Factory()
  12. factory.protocol = SimpleLogger
  13. reactor.listenTCP(1234, factory)
  14. reactor.run()

参考来自:

http://acen-chen.javaeye.com/blog/290179

http://twistedmatrix.com/projects/core/documentation/howto/clients.html

============================================================== 以下代码与上面无关

//部分二: 一个server实例

 

  1. # -*- coding: UTF-8 -*-
  2. #Twisted MMORPG
  3. from twisted.internet.protocol import Factory
  4. from twisted.protocols.basic import LineOnlyReceiver
  5. from twisted.internet import reactor
  6. import random
  7. import string
  8. class Game(LineOnlyReceiver):
  9.     def lineReceived(self, data):
  10.         self.factory.sendAll("%s" % (data))
  11.         
  12.         def getId(self):
  13.             return str(self.transport.getPeer())
  14.         
  15.         def connectionMade(self):
  16.             print "New User Login:", self.getId()
  17.             self.transport.write("欢迎来到MMO世界!\n")
  18.             self.factory.addClient(self)
  19.             
  20.         def connectionLost(self, reason):
  21.             self.factory.delClient(self)
  22.                            
  23. class GameFactory(Factory):
  24.     protocol = Game
  25.     def __init__(self):
  26.         self.clients = []
  27.         self.player = []
  28.         self.msg=''
  29.         self.x = range(100,700)
  30.         self.y = range(100,500)
  31.     
  32.     def getPlayerId(self):
  33.         return len(self.player)
  34.     
  35.     def addClient(self, newclient):
  36.         self.clients.append(newclient)
  37.         
  38.     def delClient(self, client):
  39.         self.clients.remove(client)
  40.     
  41.     def sendAll(self, data):
  42.     #print data
  43.         if data.find('')!=-1:
  44.             proto.transport.write('\0')
  45.         else:
  46.             arr = data.split(':')
  47.             prefix = arr[0]
  48.             content = arr[1]
  49.             if prefix.find('player')!=-1:
  50.                 newPlayer = [content,str(random.randrange(200, 600)),str(random.randrange(150,350)),str(random.randrange(1,5))]
  51.                 self.player.append(newPlayer)
  52.                 self.msg = ' 玩家 '+content+' 进入游戏!'
  53.                 #广播所有玩家的位置
  54.                 temp = []
  55.                 playerData = ':::'
  56.                 for pos in self.player:
  57.                     temp.append(string.join(pos,'---'))
  58.                 
  59.                 playerData = playerData+string.join(temp,'***')
  60.                 for proto in self.clients:
  61.                     proto.transport.write('[系统]: '+self.msg+'\n')
  62.                     proto.transport.write(playerData)
  63.             elif prefix.find('pos')!=-1:
  64.                 playerName,x,y = content.split('---')
  65.                 i = 0
  66.                 for p in self.player:
  67.                     if p[0]==playerName:
  68.                         p[1]=x
  69.                         p[2]=y
  70.                 for proto in self.clients:
  71.                     proto.transport.write(data)
  72.             else:
  73.                 self.msg = data
  74.                 for proto in self.clients:
  75.                     proto.transport.write(self.msg+'\n')
  76.                         
  77. reactor.listenTCP(8006, GameFactory())
  78. reactor.run()

// 部分三一个client例子,与前文不相关

 

  1. from twisted.internet.protocol import ClientCreator, Protocol
  2. from twisted.protocols.basic import LineReceiver
  3. from twisted.internet import reactor
  4. import sys

  5. class Sender(Protocol):
  6.     def sendCommand(self, command):
  7.         print "invio", command
  8.         self.transport.write(command)
  9.     
  10.     def dataReceived(self, data):
  11.         print "DATA", data
  12.         
  13. PORT = 5005
  14. HOST = 'localhost'

  15. def sendCommand(command):
  16.     def test(d):
  17.         print "Invio ->", command
  18.         d.sendCommand(command)
  19.         
  20.     c = ClientCreator(reactor, Sender)
  21.     c.connectTCP(HOST, PORT).addCallback(test)

  22. if __name__ == '__main__':
  23.     if len(sys.argv) != 2 or sys.argv[1] not in ['stop', 'next_call', 'force']:
  24.         sys.stderr.write('Usage: %s: {stop|next_call|force}\n' % sys.argv[0])
  25.         sys.exit(1)
  26.     sendCommand(sys.argv[1]+'\n')
  27.     reactor.run()
阅读(1718) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~