python tornado websocket 多聊天室(返回消息给部分连接者)
python tornado 构建多个聊天室, 多个聊天室之间相互独立, 实现服务器端将消息返回给相应的部分客户端!
chatHome.py // 服务器端, 渲染主页 --》 聊天室建立websocket连接 --》 服务器端记录连接 --》 服务器端接收消息,判断聊天室,返回最新消息到对应聊天室
#-*-coding:utf-8-*-
__author__ = 'zhouwang'
import json
import tornado.web
import tornado.websocket
import tornado.httpserver
import tornado.ioloop
import tornado.options
from uuid import uuid4 class ChatHome(object):
'''
处理websocket 服务器与客户端交互
'''
chatRegister = {} def register(self, newer):
'''
保存新加入的客户端连接、监听实例,并向聊天室其他成员发送消息!
'''
home = str(newer.get_argument('n')) #获取所在聊天室
if home in self.chatRegister:
self.chatRegister[home].append(newer)
else:
self.chatRegister[home] = [newer] message = {
'from': 'sys',
'message': '%s 加入聊天室(%s)' % (str(newer.get_argument('u')), home)
}
self.callbackTrigger(home, message) def unregister(self, lefter):
'''
客户端关闭连接,删除聊天室内对应的客户端连接实例
'''
home = str(lefter.get_argument('n'))
self.chatRegister[home].remove(lefter)
if self.chatRegister[home]:
message = {
'from': 'sys',
'message': '%s 离开聊天室(%s)' % (str(lefter.get_argument('u')), home)
}
self.callbackTrigger(home, message) def callbackNews(self, sender, message):
'''
处理客户端提交的消息,发送给对应聊天室内所有的客户端
'''
home = str(sender.get_argument('n'))
user = str(sender.get_argument('u'))
message = {
'from': user,
'message': message
}
self.callbackTrigger(home, message) def callbackTrigger(self, home, message):
'''
消息触发器,将最新消息返回给对应聊天室的所有成员
'''
for callbacker in self.chatRegister[home]:
callbacker.write_message(json.dumps(message)) class chatBasicHandler(tornado.web.RequestHandler):
'''
主页, 选择进入聊天室
'''
def get(self, *args, **kwargs):
session = uuid4() #生成随机标识码,代替用户登录
self.render('chat/basic.html', session = session) class homeHandler(tornado.web.RequestHandler):
'''
聊天室, 获取主页选择聊天室跳转的get信息渲染页面
'''
def get(self, *args, **kwargs):
n = self.get_argument('n') #聊天室
u = self.get_argument('u') #用户
self.render('chat/home.html', n=n, u=u) class newChatStatus(tornado.websocket.WebSocketHandler):
'''
websocket, 记录客户端连接,删除客户端连接,接收最新消息
'''
def open(self):
n = str(self.get_argument('n'))
self.write_message(json.dumps({'from':'sys', 'message':'欢迎来到 聊天室(%s)' % n})) #向新加入用户发送首次消息
self.application.chathome.register(self) #记录客户端连接 def on_close(self):
self.application.chathome.unregister(self) #删除客户端连接 def on_message(self, message):
self.application.chathome.callbackNews(self, message) #处理客户端提交的最新消息 class Application(tornado.web.Application):
def __init__(self):
self.chathome = ChatHome() handlers = [
(r'/', chatBasicHandler),
(r'/home/', homeHandler),
(r'/newChatStatus/', newChatStatus),
] settings = {
'template_path': 'html',
'static_path': 'static'
} tornado.web.Application.__init__(self, handlers, **settings) if __name__ == '__main__':
tornado.options.parse_command_line()
server = tornado.httpserver.HTTPServer(Application())
server.listen(8000)
tornado.ioloop.IOLoop.instance().start()
basic.html //主页, 选择进入聊天室, sessoin 设定为登录用户, GET: n指定聊天室, u指定用户
<body>
<h1>你好 !{{ session }} <br> 欢迎来到聊天室!</h1>
<a href="/home/?n=1&u={{ session }}"> 聊天室一 </a> <a href="/home/?n=2&u={{ session }}"> 聊天室二 </a>
</body>
home.html //聊天室,建立websocket连接,发送消息,接受消息,根据最新消息的发送者处理消息格式并写入页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script src="http://libs.baidu.com/jquery/1.10.2/jquery.min.js"></script>
<script>
$(function(){
n = $("#n").val()
u = $("#u").val() $("#btn").click(function(){
sendText()
})
function requestText(){
host = "ws://localhost:8000/newChatStatus/?n=" + n + "&u=" +u
websocket = new WebSocket(host) websocket.onopen = function(evt){} // 建立连接
websocket.onmessage = function(evt){ // 获取服务器返回的信息
data = $.parseJSON(evt.data)
if(data['from']=='sys'){
$('#chatinfo').append("<p style='width: 100%; text-align:center; font-size: 16px; color: green'>" + data['message'] + "</p>");
}else if(data['from']==u){
$('#chatinfo').append("<p style='width: 100%; text-align:right; font-size:15px'>" + u + ": <br>" +"<span style='color: blue'>" + data['message'] + "</span>" + "</p>");
}else{
$('#chatinfo').append("<p style='width: 100%; text-align:left; font-size:15px'>" + data['from'] + ": <br>" +"<span style='color: red'>" + data['message'] + "</span>" + "</p>");
} }
websocket.onerror = function(evt){}
} requestText() // 开始 websocket function sendText(){ // 向服务器发送信息
websocket.send($("#chat_text").val())
}
}) </script>
</head>
<body>
<div align="center">
<div style="width: 70%">
<h1>聊天室({{ n }})!</h1>
<input type="hidden" value="{{ n }}" id="n">
<input type="hidden" value="{{ u }}" id="u"> <div id="chatinfo" style="padding:10px;border: 1px solid #888">
<!-- 聊天内容 -->
</div> <div style="clear: both; text-align:right; margin-top: 20px">
<input type="text" name="chat_text" id="chat_text">
<button id="btn">发送</button>
</div>
</div>
</div>
</body>
</html>
python tornado websocket 多聊天室(返回消息给部分连接者)的更多相关文章
- Ext JS学习第十六天 事件机制event(一) DotNet进阶系列(持续更新) 第一节:.Net版基于WebSocket的聊天室样例 第十五节:深入理解async和await的作用及各种适用场景和用法 第十五节:深入理解async和await的作用及各种适用场景和用法 前端自动化准备和详细配置(NVM、NPM/CNPM、NodeJs、NRM、WebPack、Gulp/Grunt、G
code&monkey Ext JS学习第十六天 事件机制event(一) 此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件 ...
- WebSocket 网页聊天室
先给大家开一个原始的websocket的连接使用范例 <?php /* * recv是从套接口接收数据,也就是拿过来,但是不知道是什么 * read是读取拿过来的数据,就是要知道recv过来的是 ...
- 关于websocket制作聊天室的的一些总结
websocket的总结 在一个聊天室系统中,常常使用websocket作为通信的主要方式.参考地址:https://www.jianshu.com/p/00e... 关于自己的看法:websocke ...
- 基于WebSocket实现聊天室(Node)
基于WebSocket实现聊天室(Node) WebSocket是基于TCP的长连接通信协议,服务端可以主动向前端传递数据,相比比AJAX轮询服务器,WebSocket采用监听的方式,减轻了服务器压力 ...
- websocket+golang聊天室
原文地址: http://www.niu12.com/article/3 websocket+golang聊天室 main.go和index.html放在同一目录下 main.go package m ...
- Tornado WebSocket简单聊天
Tornado实现了对socket的封装:tornado.web.RequestHandler 工程目录: 1.主程序 manage.py import tornado.web import torn ...
- Python开发一个WEB聊天室
项目实战:开发一个WEB聊天室 功能需求: 用户可以与好友一对一聊天 可以搜索.添加某人为好友 用户可以搜索和添加群 每个群有管理员可以审批用户的加群请求,群管理员可以用多个,群管理员可以删除.添加. ...
- 基于webSocket的聊天室
前言 不知大家在平时的需求中有没有遇到需要实时处理信息的情况,如站内信,订阅,聊天之类的.在这之前我们通常想到的方法一般都是采用轮训的方式每隔一定的时间向服务器发送请求从而获得最新的数据,但这样会浪费 ...
- PHP websocket之聊天室实现
PHP部分 <?php error_reporting(E_ALL); set_time_limit(0);// 设置超时时间为无限,防止超时 date_default_timezone_set ...
随机推荐
- Atitit prj 项目管理与行政管理(1)------项目环境的概览与建立
Atitit prj 项目管理与行政管理(1)------项目环境的概览与建立 1. 环境的4大特点 (1)多样性与复杂性. (2)差异性.(3)变异性.(4)关联性.2 2. 环境的分类,最常用使用 ...
- Atitit dsl实现(1)------异常的库模式实现 异常的ast结构
Atitit dsl实现(1)------异常的库模式实现 异常的ast结构 1.1. Keyword 1 1.2. 异常的ast模型 1 1.3. Astview的jar org.eclipse. ...
- iOS-推送通知详解
这是一篇编译的文章,内容均出自Parse.com的iOS开发教程,同时作者还提供了视频讲解.本文将带领开发者一步一步向着iOS推送通知的深处探寻,掌握如何配置iOS推送通知的奥义. 介绍一点点背景资料 ...
- Servlet开发技术,创建,以及Servlet的配置,web.xml的配置
直接上图,不废话!!! 第一:首先在Eclipse的包资源管理器中,单机鼠标右键,在弹出的快捷键菜单中选择“新建”/Servlet命令,在弹出的对话框中输入新建的Servlet所在的包和类名,然后单击 ...
- 遍历后台的List,让前台的多选宽被选中
后端代码: /** * 获取优惠卷分页信息 * * * @param ph * 包括查询条件以及分页查询条件 * */ @Override public DataGrid<AppCmsCoupo ...
- 在jQuery ajax中按钮button和submit的区别分析
在使用jQuery ajax的get方法进行页面传值,不能用submit,否则无刷新获取数据展示 点击submit提交按钮,sendPwd.php通过$_POST接收传过来的值,然后echo一段数据. ...
- Liferay7 BPM门户开发之37: Liferay7下的OSGi Hook集成开发
hook开发是Liferay客制扩展的一种方式,比插件灵活,即可以扩展liferay门户,也能对原有特性进行更改,Liferay有许多内置的服务,比如用hook甚至可以覆盖Liferay服务. 可作为 ...
- 《PHP Manual》阅读笔记3 —— 类与对象
1.PHP 中的所有函数和类都具有全局作用域,可以定义在一个函数之内而在之外调用,反之亦然. PHP 不支持函数重载,也不可能取消定义或者重定义已声明的函数. 当一个函数是有条件被定义时,必须在调用函 ...
- Javascript动画效果(四)
Javascript动画效果(四) 前面我们自己写了一个小小的关于js动画的插件,下面我们来使用之前的框架来完成我们想要的动画效果.我们经常在淘宝网中看到,鼠标经过某一图片时,该图片有从上滚出而又从下 ...
- 如何解读SQL Server日志(2/3)
接下来说说返回的RowLogo Content列,例子中返回了三个列.这些列包含了数据操作的"有效工作负载(Playload)"记录.根据不同操作类型有效负载的内容也是不同的,但是 ...