websocket 与 tornado 的结合
对于socket是不陌生的,但是对于websocket我却是陌生的,不同于https,在网页中使用websocket可以同样起到ajax的作用,默默发送数据。。。
在script中:
ws = new WebSocket("ws://127.0.0.1:8888/chat");
//ws接收信息
ws.onmessage = function (event) {
$('.container').append(event.data);
};
//服务端关闭,触发函数
ws.onclose = function () { };
//发送信息
function sendMessage() {
ws.send($('#txt').val());
}
在tornado中有专门针对websocket请求的模块,不再是https的tornado.web.Resquest而是tornado.websocket :
import tornado.web
import tornado.ioloop
import tornado.websocket
class IndexHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs):
self.render('index.html') users = set()
class ChatHandler(tornado.websocket.WebSocketHandler): def open(self, *args, **kwargs):
"""
客户端和服务端已经建立连接
1. 连接
2. 握手
:param args:
:param kwargs:
:return:
"""
users.add(self) def on_message(self, message):
content = self.render_string('message.html',msg=message)
for client in users:
client.write_message(content) def on_close(self):
"""
客户端主动关闭连接
:return:
"""
users.remove(self) def run():
settings = {
'template_path': 'templates',
'static_path': 'static',
}
application = tornado.web.Application([
(r"/", IndexHandler),
(r"/chat", ChatHandler), ], **settings)
application.listen(8888)
tornado.ioloop.IOLoop.instance().start() if __name__ == "__main__":
run()
通过socket完成接受websocket数据的代码
import socket
import base64
import hashlib def get_headers(data):
"""
将请求头格式化成字典
:param data:
:return:
"""
header_dict = {}
data = str(data, encoding='utf-8') header, body = data.split('\r\n\r\n', 1)
header_list = header.split('\r\n')
for i in range(0, len(header_list)):
if i == 0:
if len(header_list[i].split(' ')) == 3:
header_dict['method'], header_dict['url'], header_dict['protocol'] = header_list[i].split(' ')
else:
k, v = header_list[i].split(':', 1)
header_dict[k] = v.strip()
return header_dict def send_msg(conn, msg_bytes):
import struct token = b"\x81"
length = len(msg_bytes)
if length < 126:
token += struct.pack("B", length)
elif length <= 0xFFFF:
token += struct.pack("!BH", 126, length)
else:
token += struct.pack("!BQ", 127, length) msg = token + msg_bytes
conn.send(msg)
return True sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('127.0.0.1', 8002))
sock.listen(5) # 等待用户连接
conn, address = sock.accept()
# [握手消息]
data = conn.recv(8096)
headers = get_headers(data)
# for k,v in headers.items():
# print(k,v)
magic_string = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
value = headers['Sec-WebSocket-Key'] + magic_string
ac = base64.b64encode(hashlib.sha1(value.encode('utf-8')).digest()) response_tpl = "HTTP/1.1 101 Switching Protocols\r\n" \
"Upgrade:websocket\r\n" \
"Connection:Upgrade\r\n" \
"Sec-WebSocket-Accept:%s\r\n" \
"WebSocket-Location:ws://%s%s\r\n\r\n"
# 获取[握手消息],magic string,sha1加密
# 发送会客户端
response_str = response_tpl % (ac.decode('utf-8'), headers['Host'], headers['url'])
conn.send(bytes(response_str, encoding='utf-8')) while True:
info = conn.recv(8096)
payload_len = info[1] & 127
if payload_len == 126:
extend_payload_len = info[2:4]
mask = info[4:8]
decoded = info[8:]
elif payload_len == 127:
extend_payload_len = info[2:10]
mask = info[10:14]
decoded = info[14:]
else:
extend_payload_len = None
mask = info[2:6]
decoded = info[6:] bytes_list = bytearray()
for i in range(len(decoded)):
chunk = decoded[i] ^ mask[i % 4]
bytes_list.append(chunk)
body = str(bytes_list, encoding='utf-8') send_msg(conn,bytes(body,encoding='utf-8'))
对于具体的详解请看:https://www.cnblogs.com/wupeiqi/p/6558766.html
websocket 与 tornado 的结合的更多相关文章
- python的websocket实现Tornado
1.使用flask的扩展: pip install flask-socketio 2.Tornado提供较好的ws(websocket)支持 参考:1.http://www.jianshu.com/p ...
- python tornado websocket 多聊天室(返回消息给部分连接者)
python tornado 构建多个聊天室, 多个聊天室之间相互独立, 实现服务器端将消息返回给相应的部分客户端! chatHome.py // 服务器端, 渲染主页 --> 聊天室建立web ...
- Tornado websocket应用
应用场景 WebSocket 的特点如下 适合服务器主动推送的场景(好友上线,即时聊天信息,火灾警告,股票涨停等) 相对于Ajax和Long poll等轮询技术,它更高效,不耗费网络带宽和计算资源 它 ...
- [tornado]websocket 最简单demo
想法 前两天想看看django 长轮询或者是websocket的方案,发现都不太好使. tornado很适合做这个工作,于是找了些资料,参照了做了个最简单demo,以便备用. 具体的概念就不说了,to ...
- tornado+websocket+mongodb实现在线视屏文字聊天
最近学了tornado和mongo,所以结合websocket 实现一个聊天功能,从而加深一下相关知识点的印象 1.websocket概览 webscoket是一种全双工通信模式的协议,客户端连接服务 ...
- 用tornado实现一个简单的websocket样例
想用SPRING MVC,NODE.JS EXPRESS,TORNADO实现同一个功能,开阔一下视野. 先来TORNADO的吧.. 客户端代码都差不多,主要是服务端代码. TORNADO的说法: ht ...
- 不用的代码,存一份--用tornado实现的websocket
因为现在使用Channels来实现啦, 这样就在Django的体系里自已弄完了. 方便后期代码维护和服务器部署. 这份土陋的东东,就放起来吧. 毕竟,通过读取文件来返回实时websocket,不适应于 ...
- tornado WebSocket详解
1.什么是WebSocketwebsocket和长轮询的区别是客户端和服务器之间是持久连接的双向通信.协议使用ws://URL格式,但它在是在标准HTTP上实现的. 2.tornado的WebSock ...
- tornado之WebSocket
WebSocket WebSocket是HTML5规范中新提出的客户端-服务器通讯协议,协议本身使用新的ws://URL格式. WebSocket 是独立的.创建在 TCP 上的协议,和 HTTP 的 ...
随机推荐
- openfire的SSL双向认证增加android客户端证书库步骤
过程 需要新制作PKCS12证书库.CER证书.转换为androidBKS证书,最后把客户端的CER证书导入进im服务器的私钥库client.truststore,然后替换原证书. 新证书生成步骤 ...
- 在Go语言中基础的Redis操作
在Go语言中基础的Redis操作 需要先安装redigo go get "github.com/garyburd/redigo/redis" Go语言Redis客户端的简单示例 连 ...
- 如何开会——高效会议八项原则
引子 今天看到一段有趣的话,忍不住记录下来吧! 1. 任何事情只要能开会解决的,一定要开会解决,这多威风,多热闹啊. 2. 会前千万不要准备什么议程,这样开会就会惊喜多多,会议一定低效. 3. 会前千 ...
- springBoot(9)---定时任务,异步任务
定时任务,异步任务 一.定时任务 1.步骤: 1:在启动类上写@EnableScheduling注解 2:在要定时任务的类上写@component 3:在要定时执行的方法上写@Scheduled(fi ...
- python的pyspider框架下爬虫
1.将框架下载好之后,控制台运行pyspider 2.浏览器打开http://localhost:5000 3.创建项目 页面区域介绍: 整个页面分为两栏,左边是爬取页面预览区域,右边是代码编写区域. ...
- 阿里云CentOS安装配置Python3.7及pip3
一.安装Python3.7 安装依赖包 yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqli ...
- koa2入门使用总结
koa2的介绍 Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小.更富有表现力.更健壮的基石. 通过利用 async ...
- man sm-notify(sm-notify命令中文手册)
本人译作集合:http://www.cnblogs.com/f-ck-need-u/p/7048359.html sm-notify命令是用来发送重启通知信息给NFS对端的,在锁状态恢复过程中起着至关 ...
- SpringBoot学习(六)-->SpringBoot的自动配置的原理
Spring Boot的自动配置的原理 Spring Boot在进行SpringApplication对象实例化时会加载META-INF/spring.factories文件,将该配置文件中的配置载入 ...
- 一个简单的Code First建立
1]从VS中建立一个mvc程序 记得添加NuGet包 然后在web.config中添加链接数据库的语句 <connectionStrings> <add name="Ent ...