zoukankan      html  css  js  c++  java
  • python tornado websocket 多聊天室(返回消息给部分连接者)

    python tornado 构建多个聊天室, 多个聊天室之间相互独立, 实现服务器端将消息返回给相应的部分客户端!

    chatHome.py    // 服务器端, 渲染主页 --》 聊天室建立websocket连接 --》 服务器端记录连接 --》 服务器端接收消息,判断聊天室,返回最新消息到对应聊天室

      1 #-*-coding:utf-8-*-
      2 __author__ = 'zhouwang'
      3 import json
      4 import tornado.web
      5 import tornado.websocket
      6 import tornado.httpserver
      7 import tornado.ioloop
      8 import tornado.options
      9 from uuid import uuid4
     10 
     11 class ChatHome(object):
     12     '''
     13         处理websocket 服务器与客户端交互
     14     '''
     15     chatRegister = {}
     16 
     17     def register(self, newer):
     18         '''
     19             保存新加入的客户端连接、监听实例,并向聊天室其他成员发送消息!
     20         '''
     21         home = str(newer.get_argument('n'))     #获取所在聊天室
     22         if home in self.chatRegister:
     23             self.chatRegister[home].append(newer)
     24         else:
     25             self.chatRegister[home] = [newer]
     26 
     27         message = {
     28             'from': 'sys',
     29             'message': '%s 加入聊天室(%s)' % (str(newer.get_argument('u')), home)
     30         }
     31         self.callbackTrigger(home, message)
     32 
     33     def unregister(self, lefter):
     34         '''
     35             客户端关闭连接,删除聊天室内对应的客户端连接实例
     36         '''
     37         home = str(lefter.get_argument('n'))
     38         self.chatRegister[home].remove(lefter)
     39         if self.chatRegister[home]:
     40             message = {
     41                 'from': 'sys',
     42                 'message': '%s 离开聊天室(%s)' % (str(lefter.get_argument('u')), home)
     43             }
     44             self.callbackTrigger(home, message)
     45 
     46     def callbackNews(self, sender, message):
     47         '''
     48             处理客户端提交的消息,发送给对应聊天室内所有的客户端
     49         '''
     50         home = str(sender.get_argument('n'))
     51         user = str(sender.get_argument('u'))
     52         message = {
     53             'from': user,
     54             'message': message
     55         }
     56         self.callbackTrigger(home, message)
     57 
     58     def callbackTrigger(self, home, message):
     59         '''
     60             消息触发器,将最新消息返回给对应聊天室的所有成员
     61         '''
     62         for callbacker in self.chatRegister[home]:
     63             callbacker.write_message(json.dumps(message))
     64 
     65 
     66 class chatBasicHandler(tornado.web.RequestHandler):
     67     '''
     68         主页, 选择进入聊天室
     69     '''
     70     def get(self, *args, **kwargs):
     71         session = uuid4()   #生成随机标识码,代替用户登录
     72         self.render('chat/basic.html', session = session)
     73 
     74 class homeHandler(tornado.web.RequestHandler):
     75     '''
     76         聊天室, 获取主页选择聊天室跳转的get信息渲染页面
     77     '''
     78     def get(self, *args, **kwargs):
     79         n = self.get_argument('n')      #聊天室
     80         u = self.get_argument('u')      #用户
     81         self.render('chat/home.html', n=n, u=u)
     82 
     83 
     84 class newChatStatus(tornado.websocket.WebSocketHandler):
     85     '''
     86         websocket, 记录客户端连接,删除客户端连接,接收最新消息
     87     '''
     88     def open(self):
     89         n = str(self.get_argument('n'))
     90         self.write_message(json.dumps({'from':'sys', 'message':'欢迎来到 聊天室(%s)' % n}))      #向新加入用户发送首次消息
     91         self.application.chathome.register(self)    #记录客户端连接
     92 
     93     def on_close(self):
     94         self.application.chathome.unregister(self)  #删除客户端连接
     95 
     96     def on_message(self, message):
     97         self.application.chathome.callbackNews(self, message)   #处理客户端提交的最新消息
     98 
     99 
    100 class Application(tornado.web.Application):
    101     def __init__(self):
    102         self.chathome = ChatHome()
    103 
    104         handlers = [
    105             (r'/', chatBasicHandler),
    106             (r'/home/', homeHandler),
    107             (r'/newChatStatus/', newChatStatus),
    108         ]
    109 
    110         settings = {
    111             'template_path': 'html',
    112             'static_path': 'static'
    113         }
    114 
    115         tornado.web.Application.__init__(self, handlers, **settings)
    116 
    117 if __name__ == '__main__':
    118     tornado.options.parse_command_line()
    119     server = tornado.httpserver.HTTPServer(Application())
    120     server.listen(8000)
    121     tornado.ioloop.IOLoop.instance().start()

    basic.html    //主页, 选择进入聊天室, sessoin 设定为登录用户, GET: n指定聊天室, u指定用户

    1 <body>
    2     <h1>你好 !{{ session }} <br> 欢迎来到聊天室!</h1>
    3     <a href="/home/?n=1&u={{ session }}"> 聊天室一 </a> &nbsp;        <a href="/home/?n=2&u={{ session }}"> 聊天室二 </a>
    4 </body>

    home.html         //聊天室,建立websocket连接,发送消息,接受消息,根据最新消息的发送者处理消息格式并写入页面

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title></title>
     6     <script src="http://libs.baidu.com/jquery/1.10.2/jquery.min.js"></script>
     7     <script>
     8         $(function(){
     9             n = $("#n").val()
    10             u = $("#u").val()
    11 
    12             $("#btn").click(function(){
    13                 sendText()
    14             })
    15             function requestText(){
    16                 host = "ws://localhost:8000/newChatStatus/?n=" + n + "&u=" +u
    17                 websocket = new WebSocket(host)
    18 
    19                 websocket.onopen = function(evt){}      // 建立连接
    20                 websocket.onmessage = function(evt){    // 获取服务器返回的信息
    21                     data = $.parseJSON(evt.data)  
    22                     if(data['from']=='sys'){
    23                         $('#chatinfo').append("<p style=' 100%; text-align:center; font-size: 16px; color: green'>" + data['message'] + "</p>");
    24                     }else if(data['from']==u){
    25                         $('#chatinfo').append("<p style=' 100%; text-align:right; font-size:15px'>" + u + ": <br>" +"<span style='color: blue'>" + data['message'] + "</span>" + "</p>");
    26                     }else{
    27                         $('#chatinfo').append("<p style=' 100%; text-align:left; font-size:15px'>" + data['from'] + ": <br>" +"<span style='color: red'>" + data['message'] + "</span>" + "</p>");
    28                     }
    29 
    30                 }
    31                 websocket.onerror = function(evt){}
    32             }
    33 
    34             requestText()   // 开始 websocket
    35 
    36             function sendText(){    // 向服务器发送信息
    37                 websocket.send($("#chat_text").val())
    38             }
    39         })
    40 
    41     </script>
    42 </head>
    43 <body>
    44 <div align="center">
    45     <div style=" 70%">
    46         <h1>聊天室({{ n }})!</h1>
    47         <input type="hidden" value="{{ n }}" id="n">
    48         <input type="hidden" value="{{ u }}" id="u">
    49 
    50         <div id="chatinfo" style="padding:10px;border: 1px solid #888">
    51             <!-- 聊天内容 -->
    52         </div>
    53 
    54         <div style="clear: both; text-align:right; margin-top: 20px">
    55             <input type="text" name="chat_text" id="chat_text">
    56             <button id="btn">发送</button>
    57         </div>
    58     </div>
    59 </div>
    60 </body>
    61 </html>
  • 相关阅读:
    富文本编辑器Ueditor
    记一个好用的轮播图的FlexSlider
    记一次couchbase(memcached)安装以及使用
    写了一个联动select的jquery选择器
    ios访问手机通讯录获取联系人手机号
    Swift中自定义SubString
    Swift中给UIView添加Badge
    Swift计算两个经纬度之间的球面面积
    Swift项目使用SWTableViewCell
    SQLite.Swift 中的一些用法
  • 原文地址:https://www.cnblogs.com/wowoo1121/p/5806566.html
Copyright © 2011-2022 走看看