Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5119608
  • 博文数量: 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

2013-05-27 14:03:11


文章来自: http://blog.sina.com.cn/s/blog_6acdaf6d01014aoj.html

# -*- coding: utf--8 -*-
import time
from twisted.internet import reactor
from twisted.internet.protocol import ServerFactory
from twisted.protocols.basic import LineReceiver
#from  twisted.python.threadpool import ThreadPool
import fnmatch
import shlex

class Error(Exception): pass
class WrongNumberArgumentsError(Error): pass
class WrongValueTypeError(Error): pass

class RedisServerProtocol(LineReceiver):
    def __init__(self):
        self.argc = 0               # 参数个数
        self.argl = 0               # 参数长度
        self.argv = []              # 参数数组
        self.db = 0

    def connectionMade(self):
        #self.SELECT(['', '0'])
        #self.SELECT(['', self.db])
        self.db = 0

    def dataReceived(self, data):
        return LineReceiver.dataReceived(self, data)

    def rawDataReceived(self, data):
        self.argv.append(data[:self.argl])
        self.argc -= 1
        if not self.argc:
            self.process(self.argv)
            self.argv = []
        self.setLineMode(data[self.argl+2:])

    def lineReceived(self, line):
        if self.argc:
            self.argl = int(line[1:])
            self.setRawMode()
            return
        if line[0] == '*':
            self.argc = int(line[1:])
            if self.argv:
                self.sendLine('-ERR: %r' % self.argv)
            return
        self.process(shlex.split(line))

    #获取命令行,并且将命令转化为大写,对应到本类的方法名
    def process(self, argv):
        command = argv[0].upper()
        handler = getattr(self, command, self.todo)
        #print "------------------------"
        #print argv  
        try:
            handler(argv)
        except WrongNumberArgumentsError:
            self.sendError("wrong number of arguments for %r command" % command)
        except WrongValueTypeError:
            self.sendError('Operation against a key holding the wrong kind of value')
        """except Exception, e:
            import pdb;pdb.set_trace()
            self.sendLine('-ERR %r' % e)
        """
    #目前还没有处理的命令,返回字符串ok
    def todo(self, argv):
        print 'TODO', self.argv
        self.sendOK()
    #下面send***方法的使用请查看http://blog.sina.com.cn/s/blog_6acdaf6d01013bs2.html
    #第一个字节是字符“+”,后面跟着一行表示执行结果的提示信息(line reply)比如set命令执行成功 后,会返回”+OK\r\n”
    def sendOK(self):
        self.sendLine('+OK')
     #第一个字节是字符“:”,后面跟着一个整数值(integer reply)比如incr命令,成功时会返回对象+1后的值。
    def sendInteger(self, i):
        self.sendLine(':%d' % i)
     #第一个字节是字符“$”,后面先跟一行,仅有一个数字,该数字表示下一行字符的个数(若不存在,则数字为-1)(bulk reply)比如get命令,成功时返回值的类似于“$7\r\nmyvalue”,不存在时返回的信息为“$-1\r\n”
    def sendBulk(self, bulk):
        if bulk is None:
            self.sendLine('$-1')
            return
        self.sendLine('$%d' % len(bulk))
        self.sendLine(bulk)
    第一个字节是字符“*”,后面先跟一行,仅有一个数字,该数字表示bulk reply的个数(若不存在,则数字为-1)(multi-bulk reply)
    def sendBulks(self, bulks):
        self.sendLine('*%d' % len(bulks))
        for bulk in bulks:
            self.sendBulk(bulk)
            print bulk
        #map(self.sendBulk, bulks)
    #第一个字节是字符“-”,后面跟着一行出错信息(error reply)比如lpop命令,当操作的对象不是一个链表时,会返回如下出错信息:“-ERR Operation against a key holding the wrong kind of value\r\n”
    def sendError(self, message):
        self.sendLine('-ERR %s' % message)

    def sendLine(self, line):
        #print line
        return LineReceiver.sendLine(self, line)
   
    #选择db
    def SELECT(self, argv):
        self.db = argv[1]
        self.sendOK()

    def GET(self, argv):
        if len(argv) != 2: raise WrongNumberArgumentsError
        key = argv[1]
        #self.db = [{}] * 16该fake的数据都存在该数据结构中,当然你也可以定义在自己的数据结构中,这样做的话,重启后数据就不存在,当然你也可以存在数据可或者是真实的redis中。我们的项目是做了redis的转发,取数据的时候判断测试redis中是否有该数据,没有的话去开发测试集群取该数据,并且保存在测试的redis中,作为测试准备数据,可以保证自动化测试基准版本和测试版本访问的redis数据是相同的
        value = "你自己的获取value的方法"
        self.sendBulk(value)

    def SET(self, argv):
        if len(argv) != 3: raise WrongNumberArgumentsError
        argv[1]是key
        argv[2]是value
        self.sendOK()

class RedisServer(ServerFactory):
    protocol = RedisServerProtocol
    def __init__(self):
        self.db = [{}] * 16

#指定server的实现类
reactor.listenTCP(6666, RedisServer())
#设定线程个数
reactor.suggestThreadPoolSize(30)
reactor.run()
阅读(1310) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~