基于Twisted的简单聊天室

实现了私聊,公聊。用户名密码存在redis。为了拓展,做了简单的模块。

#coding=utf8

from twisted.internet import reactor, defer

from twisted.protocols.basic import LineReceiver

from twisted.internet.protocol import Factory, Protocol, ServerFactory

import redis





class Server(ServerFactory):

        def __init__(self):

            self.users = {}

            self.last_messages = {}

            self.__db = dbServer

        #def start(self):



        #def stop(self):



        def do_login(self, pro, args):

            username, passwd = args

            if self.__db.get(username) is not None:

                if passwd != self.__db.get(username):

                    return "do_login", False, "login failed"

                else:

                    user = User(username, passwd, pro, 1)

                    self.users[username] = user

                    pro.user = user

                    return "do_login", True, "login success"

            else:

               self.__db.set(username, passwd)

               self.__db.save()

            user = User(username, passwd, pro, 1)

            self.users[username] = user

            pro.user = user

            return "do_login", True, "login success"



        def checklogin(self, user):

            return user.logined



        def do_privatemsg(self, pro, args):

            target, msg = args

            user = pro.user

            if self.checklogin(user):

                self.last_messages[user] = msg

                msg = '['+user.name+']' + msg

                return "do_privatemsg", self.users[target], msg



        def do_publicmsg(self, pro, args):

            msg = args

            user = pro.user

            print user.name

            if self.checklogin(user):

                self.last_messages[user] = msg

                msg = '['+user.name+']' + msg[0]

                return "do_publicmsg", self.users.values(), msg



class User(object):

        def __init__(self, name, passwd, pro, logined):

                self.name = name

                self.password = passwd

                self.nick_name = '&&' + name + '&&'

                self.proto = pro

                self.logined = logined



class ChatProtocol(LineReceiver):

        #line format: "func target_name *contents"

        #example: "privatemsg hs how are you....."

        #example: "publicmsg how are you....."

        #example: "login hs password"

        def __init__(self):

            self.user = 0

            self.pro = self



        def connectionMade(self):

            self.sendLine("please input: 'login,username,password'")



        def lineReceived(self, line):

            defer.maybeDeferred(self.parse, line).addCallback(self.processor).addCallback(self.ack)



        def parse(self, line):

            result = line.split(',')

            func = result[0]

            args = result[1:]

            return func, args



        def processor(self, args):

            func, arg = args

            _func = getattr(server, 'do_' + func)

            if _func:

                return _func(self.pro, arg)

            else:

                raise Exception("xxxxx")



        def ack(self, args):

            func, target, msg = args

            if func == 'do_login':

                if not target:

                   self.kickOut()

                self.sendLine(msg)

            elif func == 'do_privatemsg':

                target.proto.sendLine(msg)

            elif func == 'do_publicmsg':

                for user in target:

                    if user.proto != self:

                        user.proto.sendLine(msg)

            else:

                pass



        def kickOut(self):

            self.sendLine('passwd is wrong')

            self.transport.loseConnection()



class redisServer(object):

        def __init__(self):

            r = redis.Redis(host='localhost', port=6379, db=0)

            self.db = r

        def set(self, key, value):

            self.db.set(key, value)

        def save(self):

            self.db.save()

        def get(self, key):

            return self.db.get(key)





dbServer = redisServer()

server = Server()

server.protocol = ChatProtocol

reactor.listenTCP(8008,server)

print 'server start!'

reactor.run()

  

你可能感兴趣的:(聊天室)