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>
  • 相关阅读:
    POJ 3041 Asteroids 最小点覆盖 == 二分图的最大匹配
    POJ 3083 Children of the Candy Corn bfs和dfs
    POJ 2049 Finding Nemo bfs 建图很难。。
    POJ 2513 Colored Sticks 字典树、并查集、欧拉通路
    POJ 1013 Counterfeit Dollar 集合上的位运算
    POJ 2965 The Pilots Brothers' refrigerator 位运算枚举
    无聊拿socket写的100以内的加法考试。。。
    POJ 1753 Flip Game
    初学socket,c语言写的简单局域网聊天
    汇编语言 复习 第十一章 标志寄存器
  • 原文地址:https://www.cnblogs.com/wowoo1121/p/5806566.html
Copyright © 2011-2022 走看看