找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

查看: 11869|回复: 0

[代码与实例] 用tornado写websocket聊天室

50

主题

1057

帖子

1108

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
1108

活跃会员热心会员最佳导师默默耕耘突出贡献优秀版主荣誉管理论坛元老

blueelwang 发表于 2014-6-17 11:51:18 | 显示全部楼层 |阅读模式
在tornado官方的websocket demo 基础上改写的,增加了session(用mongo来存储);增加了用户列表;有用户注册功能/register 登录/login 登录图片验证;

  1. #-*- coding: utf-8 -*-

  2. import logging,random,uuid,string,time
  3. import tornado.escape
  4. import tornado.ioloop
  5. import tornado.options
  6. import tornado.web
  7. import tornado.websocket
  8. import os.path

  9. from tornado.web import HTTPError
  10. from session.auth import MongoAuthentication
  11. from session.session import MongoSessions
  12. from BaseHandler import BaseHandler
  13. from tornado.options import define, options
  14. from verify_code import make as make_verify_code

  15. define("port", default=8888, help="run on the given port", type=int)

  16. '''
  17.     开发人:
  18.         ROY (火炎神)
  19.     时间:
  20.         2014/6/14

  21.     服务端的架构体系:
  22.         db  : newjh (mongodb)
  23.         b/s : websocket
  24.         session : 基于mongodb
  25.         verify_code : 校验码验证
  26. '''

  27. class Application(tornado.web.Application):
  28.     def __init__(self):
  29.         handlers = [
  30.             (r"/register",RegisterHandler),
  31.             (r"/login",LoginHandler),
  32.             (r"/logout",LogoutHandler),
  33.             (r"/", MainHandler),
  34.             (r"/chatsocket", ChatSocketHandler),
  35.             (r"/verifycode",VerifyCode),
  36.         ]
  37.         settings = dict(
  38.             cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",
  39.             template_path=os.path.join(os.path.dirname(__file__), "templates"),
  40.             static_path=os.path.join(os.path.dirname(__file__), "static"),
  41.             xsrf_cookies=False,
  42.         )

  43.         self.sessions = MongoSessions("newjh", "sessions", timeout=10)
  44.         self.auth = MongoAuthentication("newjh", "user")
  45.         self.sessions.clear_all_sessions()
  46.         tornado.web.Application.__init__(self, handlers, **settings)

  47. class RegisterHandler(BaseHandler):
  48.     def get(self):
  49.         self.render("register.html")
  50.     def post(self):
  51.         username = self.get_argument('username',None)
  52.         _username = self.get_argument('_username',None)
  53.         pwd = self.get_argument('pwd',None)
  54.         #pwd = md5(pwd).hexdigest()
  55.         print 'argument %s'%self.request.arguments
  56.         user = self.db.user.find_one({'uid':username})
  57.         if user :
  58.             self.write("帐号已经注册了")
  59.         else:
  60.             code = self.get_argument('code',None)
  61.             cookiecode = self.get_secure_cookie('verify_code')
  62.             print 'register code / server code',code,cookiecode
  63.             if code != cookiecode : raise HTTPError(403,'验证不对')
  64.             user = {
  65.                 'uid':username,
  66.                 'pwd':pwd,
  67.                 'name':_username,
  68.                 'gold':100000,
  69.                 'gamegold':0,
  70.                 'jewel':0,
  71.                 'regtime':time.strftime('%Y-%m-%d',time.localtime(time.time())),
  72.                 'bind':{'email':0,'mobile':0,'sec':0,'idcard':0},
  73.                 'sign':{},
  74.                 'signnum':{},
  75.             }
  76.             print 'user%s'%user
  77.             res = self.application.auth.register(user)
  78.             if not res : raise HTTPError(403)
  79.             #user = db.user.find_one({'uid':username})
  80.             res = self.begin_session(username,pwd)
  81.             if not res : raise HTTPError(403)
  82.             self.redirect('/login')

  83. class LoginHandler(BaseHandler):
  84.     def post(self):
  85.         print self.request
  86.         name = self.get_argument('name',None)
  87.         pwd = self.get_argument('pwd',None)
  88.         logging.info(('loging name pwd %s %s'%(name,pwd)))
  89.         code = self.get_argument('code',None)
  90.         cookiecode = self.get_secure_cookie('verify_code')
  91.         print 'verify code cookie',cookiecode
  92.         if code != cookiecode : raise HTTPError(403)
  93.         res = self.begin_session(name, pwd)
  94.         if not res : raise HTTPError(403)
  95.         self.redirect('/')
  96.     def get(self):
  97.         self.render("login.html")

  98. class LogoutHandler(BaseHandler):
  99.     def get(self):
  100.         self.post()

  101.     def post(self):
  102.         self.end_session()
  103.         self.redirect('/login')


  104. class VerifyCode(BaseHandler):
  105.     def get(self):
  106.         verify_code = ''.join(random.sample(string.ascii_lowercase\
  107.                       +string.digits,4))
  108.         self.set_secure_cookie("verify_code",verify_code)
  109.         content = make_verify_code(verify_code)
  110.         self.set_header('Content-Type','image/jpeg;charset=utf-8')
  111.         self.write(content)

  112. class MainHandler(BaseHandler):
  113.     def get(self):

  114.         if self.session :
  115.             _user = self.session['data']
  116.             self.render("index.html",
  117.                         messages=ChatSocketHandler.cache,
  118.                         userlist=ChatSocketHandler.userlist,
  119.                         myuser = _user)
  120.         else:
  121.             self.redirect('/login')

  122. class ChatSocketHandler(tornado.websocket.WebSocketHandler):
  123.     waiters = set()
  124.     cache = []
  125.     cache_size = 200

  126.     userlist = []
  127.     user_size = 100
  128.     user = None


  129.     def allow_draft76(self):
  130.         # for iOS 5.0 Safari
  131.         return True

  132.     def open(self):
  133.         print 'open... is start '
  134.         #self.on_message({"name":"roy","body":"welcome roy !","type":1})
  135.         ChatSocketHandler.waiters.add(self)
  136.         #self.write_message("ok!")

  137.     def on_close(self):
  138.         for i in ChatSocketHandler.userlist:
  139.             if (self.user["content"] == i["content"]) :
  140.                 ChatSocketHandler.userlist.remove(i)
  141.         print self.user
  142.         self.user["type"] = 3
  143.         user = self.user
  144.         self.user = None
  145.         ChatSocketHandler.waiters.remove(self)
  146.         ChatSocketHandler.send_updates(user)

  147.     @classmethod
  148.     def update_cache(cls, chat):
  149.         cls.cache.append(chat)
  150.         if len(cls.cache) > cls.cache_size:
  151.             cls.cache = cls.cache[-cls.cache_size:]

  152.     @classmethod
  153.     def update_user(cls, user):
  154.         for i in cls.userlist:
  155.             if (user["content"] == i["content"]) : return
  156.         #print cls.userlist
  157.         #self.user = user
  158.         cls.userlist.append(user)
  159.         if len(cls.userlist) > cls.user_size:
  160.             cls.userlist = cls.userlist[-cls.user_size:]

  161.     @classmethod
  162.     def send_updates(cls, chat):
  163.         logging.info("sending message to %d waiters", len(cls.waiters))
  164.         for waiter in cls.waiters:
  165.             try:
  166.                 waiter.write_message(chat)
  167.             except:
  168.                 logging.error("Error sending message", exc_info=True)


  169.     def on_message(self, message):
  170.         logging.info("got message %r", message)
  171.         parsed = tornado.escape.json_decode(message)
  172.         if(parsed["type"] == 1):
  173.             chat = {
  174.                 "id": str(uuid.uuid4()),
  175.                 "body": parsed["body"],
  176.                 "name": parsed["name"],
  177.                 "type": parsed["type"]
  178.                 }
  179.             chat["html"] = tornado.escape.to_basestring(
  180.                 self.render_string("message.html", message=chat))

  181.             ChatSocketHandler.update_cache(chat)
  182.             ChatSocketHandler.send_updates(chat)
  183.         if(parsed["type"] == 2):
  184.             print 'adduser start ...'
  185.             user = {
  186.                 "id": str(uuid.uuid4()),
  187.                 "content": parsed["content"],
  188.                 "type": parsed["type"]
  189.                 }
  190.             user["html"] = tornado.escape.to_basestring(
  191.                 self.render_string("user.html", user=user))
  192.             self.user = user
  193.             ChatSocketHandler.update_user(user)
  194.             ChatSocketHandler.send_updates(user)



  195. def main():
  196.     tornado.options.parse_command_line()
  197.     app = Application()
  198.     app.listen(options.port)
  199.     tornado.ioloop.IOLoop.instance().start()


  200. if __name__ == "__main__":
  201.     main()
复制代码



5. [图片] QQ图片20140616195325.jpg   

6. [图片] QQ图片20140616195410.jpg   



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表