websocket的实现--前端js,后端Django的dwebsocket
这是一个协议,和http一样,可以实现web服务器和浏览器间全双工的通信过程。具体在文章阮一峰的网络日志–Websocket教程和Socket与WebSocket了解。
1.单独前端实现,服务器用官方的ws://echo.websocket.org/
1、建立一个websocket对象
//新建一个websocket,指定服务器ip,post和地址
var websocket = new WebSocket("ws://localhost:8080");
2、一些属性
- onopen :指定连接成功后的回调函数
websocket.onopen=function(){
console.log("websocket open");
}
- onclose: 指定连接关闭后的回调函数
websocket.onclose = function(){
console.log("websocket close");
}
- onmessage: 指定收到服务器数据后的回调函数,带个参数 e,即收到的服务器的数据。
websocket.onmessage = function(e){
console.log("e.data");
document.getElementById("recv").innerHTML = e.data;
}
3、使用send() 方法像服务器发送数据
var txt = document.getElementById("sendText").value;
//发送消息
websocket.send(txt);
4、在一个html中写入,打开试试,和ws://echo.websocket.org/建立连接,发送什么,返回相同内容。服务器实现的就是简单的回声功能。
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8" />
<title>WebSocket Test</title>
</head>
<body>
<h1>Echo Test</h1>
<input id="sendText" type="text" />
<button id="sendBtn">发送</button>
<div id="recv"></div>
<script langue="javascript" type = "text/javascript">
var websocket = new WebSocket("ws://echo.websocket.org/");
//建立连接后会调用回调函数
websocket.onopen=function(){
console.log("websocket open");
document.getElementById("recv").innerHTML = "Connected";
}
websocket.onclose = function(){
console.log("websocket close");
//document.getElementById("recv").innerHTML = "closed";
}
//当接收到消息的时候会回调的函数,消息通过类里面参数e传递
websocket.onmessage = function(e){
console.log("e.data");
document.getElementById("recv").innerHTML = e.data;
}
document.getElementById("sendBtn").onclick = function(){
var txt = document.getElementById("sendText").value;
//发送消息
websocket.send(txt);
}
</script>
</body>
</html>
参考:添加链接描述
3.补充:JSON----轻量级的数据交换格式
基本语法:
- 并列数据之间用逗号(“,”)分隔
- 映射用冒号(“:”)表示
- 并列数据的集合(数组)用方括号(“ [ ] ”)表示
- 映射是集合(对象)用大括号(“{ }”)表示
JSON是JS对象的字符串表示法,使用文本表示一个JS对象的信息。跨平台的数据格式,字符集必须Unicode。
JSON和JS对象互换:
-
JSON→JS对象:
var obj = JSON.parse('{"a":"hello","b":"123"}'); //{a:"hello",b:"123"}
-
JS对象→JSON:
var json = JSON.stringify({a:"hello",b:"123"});
参考:JSON应用场景与实战
4. 补充:jQuery----JavaScript库
基础语法:
$(selector).action()
// $----定义jQuery
//(selector)---选择符,查询或查找HTML元素
// action()----执行对元素的操作
文档就绪事件:
$(document).ready(function(){
//内容
})
//简化
$(function(){
//内容
})
参考:jQuery 教程
5.实现服务器端和前端websocket交流
本来用python的Django框架来实现web服务器端的应用程序。对于Django框架实现websocket,可以用dwebsocket或channel,另外Python的另一框架Tornado对websocket的支持也很好。不过我先用了dwebsocket。python使用websocket的几种方式
Django2.0 dwebsocket0.5.12。虽然有人说这个库废弃了,但是我还是用了…网上参考大多是Django1版本的,重要参考连接Django 2.1.7 通过dwebsocket实现websocket
dwebsocket网站:https://pypi.org/project/dwebsocket/0.4.2/
在Django框架里使用websocket的步骤:
1、安装dwebsocket模块
pip install dwebsocket
2、使用方法
- 使用装饰器方式单独为某个视图函数增加websocket功能
accept_websocket----可以接受websocket请求和普通http请求 require_websocket----只接受websocket请求,拒绝普通http请求
- 在配置文件中设置中间件,使每个视图函数都可以使用websocket功能(我没用)
3、请求的流程 ----在Django框架中需要修改路由、视图函数、html文件
4、Django里的一顿操作
视图函数①:
#响应对应的http请求页面
def test_websocket_client_full(request):
return render(request,'app1/websocket_client_full.html')
视图函数②:
#响应对应html文件里发出的websocket请求
@accept_websocket
def test_websocket_full(request):
if request.is_websocket(): # 如果请求是websocket请求:
WebSocket = request.websocket
i = 0 # 设置发送至前端的次数
messages = {}
while True:
i += 1 # 递增次数 i
time.sleep(1) # 休眠1秒
# 判断是否通过websocket接收到数据
if WebSocket.has_messages():
# 存在Websocket客户端发送过来的消息
client_msg = WebSocket.read().decode()
# 设置发送前端的数据
messages = {
'time': time.strftime('%Y.%m.%d %H:%M:%S', time.localtime(time.time())),
'server_msg': 'send %d times!' % i,
'client_msg': client_msg,
}
else:
# 设置发送前端的数据
messages = {
'time':time.strftime('%Y.%m.%d %H:%M:%S',time.localtime(time.time())),
'server_msg': 'send %d times!' % i,
}
# 设置发送数据为json格式
request.websocket.send(json.dumps(messages))
路由配置①:
path('test_websocket_client_full',app1.views.test_websocket_client_full),
路由配置②:
path('test_websocket_full',app1.views.test_websocket_full),
html前端页面(用了JS的Jquery库):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
// 点击连接websocket按钮,则启动访问websocket
$('#connect_websocket').click(function () {
if(window.s){
window.s.close()
}
// 设置websocket的服务端url
var s = new WebSocket("ws://" + window.location.host + "/app1/test_websocket_full");
// 打开连接websocket服务,连接成功则打印信息
s.onopen = function () {
console.log('WebSocket open');//成功连接上Websocket
};
// 接收服务端发送过来的数据,在浏览器上刷新
s.onmessage = function (e) {
console.log('message: ' + e.data);//打印出服务端返回过来的数据
$('#messagecontainer').prepend('<p>' + e.data + '</p>');
};
window.s = s;
});
// 点击发送消息按钮,则通过websocket发送数据至服务端
$('#send_message').click(function () {
if (!window.s) {
alert("Please connect server.");
} else {
window.s.send($('#message').val());//通过websocket发送数据
}
});
// 点击关闭websocket连接
$('#close_websocket').click(function () {
if (window.s) {
window.s.close();//关闭websocket
console.log('websocket is closed!');
}
});
});
</script>
</head>
<body>
<input type="text" id="message" value="Open websocket!" />
<button type="button" id="connect_websocket">连接websocket</button>
<button type="button" id="send_message">发送 message</button>
<button type="button" id="close_websocket">关闭websocket</button>
<h1>Received Messages</h1>
<div id="messagecontainer"></div>
</body>
</html>
结果是一样的,非常感谢Django 2.1.7 通过dwebsocket实现websocket的分享,不过我碰到的问题,就是引用jquery库的时候,本地没用拷贝库从网页引用。
目前关闭socket的时候好像会报错
添加链接描述