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. class chatBasicHandler(tornado.web.RequestHandler):
  66. '''
  67. 主页, 选择进入聊天室
  68. '''
  69. def get(self, *args, **kwargs):
  70. session = uuid4() #生成随机标识码,代替用户登录
  71. self.render('chat/basic.html', session = session)
  72.  
  73. class homeHandler(tornado.web.RequestHandler):
  74. '''
  75. 聊天室, 获取主页选择聊天室跳转的get信息渲染页面
  76. '''
  77. def get(self, *args, **kwargs):
  78. n = self.get_argument('n') #聊天室
  79. u = self.get_argument('u') #用户
  80. self.render('chat/home.html', n=n, u=u)
  81.  
  82. class newChatStatus(tornado.websocket.WebSocketHandler):
  83. '''
  84. websocket, 记录客户端连接,删除客户端连接,接收最新消息
  85. '''
  86. def open(self):
  87. n = str(self.get_argument('n'))
  88. self.write_message(json.dumps({'from':'sys', 'message':'欢迎来到 聊天室(%s)' % n})) #向新加入用户发送首次消息
  89. self.application.chathome.register(self) #记录客户端连接
  90.  
  91. def on_close(self):
  92. self.application.chathome.unregister(self) #删除客户端连接
  93.  
  94. def on_message(self, message):
  95. self.application.chathome.callbackNews(self, message) #处理客户端提交的最新消息
  96.  
  97. class Application(tornado.web.Application):
  98. def __init__(self):
  99. self.chathome = ChatHome()
  100.  
  101. handlers = [
  102. (r'/', chatBasicHandler),
  103. (r'/home/', homeHandler),
  104. (r'/newChatStatus/', newChatStatus),
  105. ]
  106.  
  107. settings = {
  108. 'template_path': 'html',
  109. 'static_path': 'static'
  110. }
  111.  
  112. tornado.web.Application.__init__(self, handlers, **settings)
  113.  
  114. if __name__ == '__main__':
  115. tornado.options.parse_command_line()
  116. server = tornado.httpserver.HTTPServer(Application())
  117. server.listen(8000)
  118. 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>

python tornado websocket 多聊天室(返回消息给部分连接者)的更多相关文章

  1. Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G

    code&monkey   Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...

  2. WebSocket 网页聊天室

    先给大家开一个原始的websocket的连接使用范例 <?php /* * recv是从套接口接收数据,也就是拿过来,但是不知道是什么 * read是读取拿过来的数据,就是要知道recv过来的是 ...

  3. 关于websocket制作聊天室的的一些总结

    websocket的总结 在一个聊天室系统中,常常使用websocket作为通信的主要方式.参考地址:https://www.jianshu.com/p/00e... 关于自己的看法:websocke ...

  4. 基于WebSocket实现聊天室(Node)

    基于WebSocket实现聊天室(Node) WebSocket是基于TCP的长连接通信协议,服务端可以主动向前端传递数据,相比比AJAX轮询服务器,WebSocket采用监听的方式,减轻了服务器压力 ...

  5. websocket+golang聊天室

    原文地址: http://www.niu12.com/article/3 websocket+golang聊天室 main.go和index.html放在同一目录下 main.go package m ...

  6. Tornado WebSocket简单聊天

    Tornado实现了对socket的封装:tornado.web.RequestHandler 工程目录: 1.主程序 manage.py import tornado.web import torn ...

  7. Python开发一个WEB聊天室

    项目实战:开发一个WEB聊天室 功能需求: 用户可以与好友一对一聊天 可以搜索.添加某人为好友 用户可以搜索和添加群 每个群有管理员可以审批用户的加群请求,群管理员可以用多个,群管理员可以删除.添加. ...

  8. 基于webSocket的聊天室

    前言 不知大家在平时的需求中有没有遇到需要实时处理信息的情况,如站内信,订阅,聊天之类的.在这之前我们通常想到的方法一般都是采用轮训的方式每隔一定的时间向服务器发送请求从而获得最新的数据,但这样会浪费 ...

  9. PHP websocket之聊天室实现

    PHP部分 <?php error_reporting(E_ALL); set_time_limit(0);// 设置超时时间为无限,防止超时 date_default_timezone_set ...

随机推荐

  1. fir.im Weekly - 不能错过的 GitHub Top 100 开源库

    好的工具&资源,会带来更多的灵感.本期 fir.im Weekly 精选了一些实用的 iOS,Android 的使用工具和源码分享,还有前端.UI方面的干货.一起来看下:) Swift 开源项 ...

  2. 据说,每一个 iOSer 都想要一张 Swift 大会门票

    据说,每一个 iOSer 都想要一张中国首届 Swift 开发者大会的门票: 那么,福利来了-- fir.im 作为中国首届 Swift 大会的唯一钻石赞助商,有最后 2 张价值 600 多的门票(已 ...

  3. js选项卡

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  4. Tomcat源码解读系列(一)——server.xml文件的配置

    Tomcat是J2EE开发人员最常用到的开发工具,在Java Web应用的调试开发和实际部署中,我们都可以看到Tomcat的影子.大多数时候,我们可以将Tomcat当做一个黑盒来看待,只需要将编写的J ...

  5. 关于BUG率的计算和它的实际意义的思考

    我的微信号是Shalayang,以下是我的二维码名片,欢迎添加. 问题1:bug率有什么作用? my opion:用处有很多,需要具体情况具体分析,不过主要作用一般是来评价工作产品的质量.如果bug率 ...

  6. css多行文本省略号问题

    已知,单行文本溢出内容用省略号代替,css代码如下: text-overflow: ellipsis; 溢出部分用...代替 white-space: nowrap; //强制在一行显示 overfl ...

  7. iOS越狱开发(一)

    做越狱开发也有一些时间了,有很多东西想总结一下,希望给他人一些借鉴,也是自己对过去开发经历的一些总结.个人不推荐使用盗版,这里主要以技术介绍为主. 这个系列里面主要介绍怎样进行越狱开发,涉及到以下几个 ...

  8. datagridview控件去除页码

    开启datagridview的分页功能,默认页码是是显示的 为了不让页码显示,可以在绑定数据的是将其隐藏掉 gvLogName.BottomPagerRow.Visible = false; gvLo ...

  9. CSS裁剪clip

    × 目录 [1]定义 [2]RECT [3]应用 前面的话 CSS裁剪clip这个属性平时用的不多,但其实它并不是CSS3的新属性,很早就开始出现了.本文将介绍关于clip属性的相关知识 定义 一个绝 ...

  10. Android开发之时间日期1

     对于手机的时间日期设置估计大家一定都不陌生吧,今天做了一个关于时间日期设置的小例子,其中遇到一个问题,求指导,如何使设置的时间日期和手机系统同步?还望高手指点一二. 先不说这个了,分享一下我的小例子 ...