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='width: 100%; text-align:center; font-size: 16px; color: green'>" + data['message'] + "</p>");
24                     }else if(data['from']==u){
25                         $('#chatinfo').append("<p style='width: 100%; text-align:right; font-size:15px'>" + u + ": <br>" +"<span style='color: blue'>" + data['message'] + "</span>" + "</p>");
26                     }else{
27                         $('#chatinfo').append("<p style='width: 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="width: 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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM