一、创建项目(dj_websocket):
1、创建项目
python django-admin.py startproject dj_websocket
2、进入项目
cd dj_websocket
3、创建APP(myapp)
python manage.py startapp myapp
4、创建,static (静态文件夹),已经 templates(模板文件夹)
mkdir static
mkdir templates
二、配置 settings.py
1、在 INSTALLED_APPS 列表加上(myapp):
INSTALLED_APPS = [
...,
'myapp',
]
2、在 TEMPLATES 列表的DIRS加上:
TEMPLATES = [
{
...,
'DIRS': [os.path.join(BASE_DIR, 'templates')],
...,
},
]
3、在文件末尾加上:
STATICFILES_DIRS = [os.path.join(BASE_DIR,'static')]
三、views.py 文件编写:
import json
import time
import datetime
from django.shortcuts import render
from dwebsocket.decorators import accept_websocket,require_websocket
# Create your views here.
def index(request):
return render(request, 'index.html',{'init':'init'})
@accept_websocket
def echo(request):
if not request.is_websocket():#判断是不是websocket连接
#如果是普通的http方法
try:
message = request.GET['message']
return HttpResponse(message)
except:
return render(request,'index.html')
else:
# 如果是websocket请求
for message in request.websocket:
request.websocket.send(message)#发送消息到客户端
#request.websocket.send(message)
# 推送10次,当然你可以无限次的推送
for i in range(10):
dt = str(datetime.datetime.now())
s={'test':f"你好 {i} {dt}"}
s=json.dumps(s).encode()
request.websocket.send(s)
time.sleep(0.1) # 间隔0.1秒
四、urls.py 文件编写:
from django.conf.urls import url
from django.contrib import admin
from myapp import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index),
url(r'^echo$', views.echo),
]
五、index.html 编写(templates文件夹)
其中使用了 jquery-1.8.3.min.js ,需要下载到我们的 static 文件夹
<html>
<head>
<meta charset="utf-8">
<title>django-websockettitle>
{% load staticfiles %}
<script src="{% static 'jquery-1.8.3.min.js' %}">script>
<script type="text/javascript">//
$(function () {
/*创建socket连接
var socket = new WebSocket("ws://" + window.location.host + "/echo");
socket.onopen = function () {
console.log('WebSocket open');//成功连接上Websocket
socket.send($('#message').val());//通过websocket发送数据
};
socket.onmessage = function (e) {
console.log('message: ' + e.data);//打印出服务端返回过来的数据
$('#messagecontainer').prepend('' + e.data + '
');
};
// Call onopen directly if socket is already open
//if (socket.readyState == WebSocket.OPEN) socket.onopen();
// 这些代码可以实现一进入页面就自动推送,不可停止
*/
$('#connect_websocket').click(function () {
if (window.s) {
window.s.close();
}
/*创建socket连接*/
var socket = new WebSocket("ws://" + window.location.host + "/echo");
socket.onopen = function () {
console.log('WebSocket open');//成功连接上Websocket
};
socket.onmessage = function (e) {
console.log('message: ' + e.data);//打印出服务端返回过来的数据
var d= $.parseJSON(e.data);
//alert(typeof(d));
$('#messagecontainer').prepend(''
+ d.test + '');
};
// Call onopen directly if socket is already open
if (socket.readyState == WebSocket.OPEN) socket.onopen();
window.s = socket;
});
$('#send_message').click(function () {
//如果未连接到websocket
if (!window.s) {
alert("websocket未连接.");
} else {
window.s.send($('#message').val());//通过websocket发送数据
}
});
$('#close_websocket').click(function () {
if (window.s) {
window.s.close();//关闭websocket
console.log('websocket已关闭');
}
});
});
//]]>script>
head>
<body>
<br>
<input type="text" id="message" value="开始..."/>
<button type="button" id="connect_websocket">连接 websocketbutton>
<button type="button" id="send_message">发送 messagebutton>
<button type="button" id="close_websocket">关闭 websocketbutton>
<h1>Received Messagesh1>
<div id="messagecontainer">
div>
{{init}}
body>
html>
六、开始执行:
这两句在这里不是必要的
python manage.py makemigrations
python manage.py migrate
运行服务器
python manage.py runserver
七、访问:
打开浏览器输入地址:http://localhost:8000/index/
我们将看到页面:
1 server.py
import websockets
import asyncio
import time
import datetime
import json
async def hello(websocket,path):
name = await websocket.recv()
print(f'A new client: {name}')
for i in range(10):
dt = str(datetime.datetime.now())
s = json.dumps({'test':f"{name} {i} {dt}"})
await websocket.send(s)
print(f'send {name} {i} {dt}')
time.sleep(0.1)
start_server = websockets.serve(hello,'localhost',8000)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
run server.py:
python server.py
2 client.py
import websockets
import asyncio
async def hello():
async with websockets.connect('ws://localhost:8000') as websocket:
name = input("what's your name?")
await websocket.send(name)
print(f"send server:{name}")
while 1:
greeting = await websocket.recv()
print(f'receive from server:{greeting}')
asyncio.get_event_loop().run_until_complete(hello())
run client.py
python client.py
input:hello
output to server
A new client: hello
send hello 0 2018-07-28 20:24:11.410886
send hello 1 2018-07-28 20:24:11.511604
send hello 2 2018-07-28 20:24:11.612339
send hello 3 2018-07-28 20:24:11.713062
send hello 4 2018-07-28 20:24:11.813771
send hello 5 2018-07-28 20:24:11.914492
send hello 6 2018-07-28 20:24:12.015099
send hello 7 2018-07-28 20:24:12.115936
send hello 8 2018-07-28 20:24:12.216658
send hello 9 2018-07-28 20:24:12.317399
output to client.py
what's your name?hello
send server:hello
receive from server:{"test": "hello 0 2018-07-28 20:24:11.410886"}
receive from server:{"test": "hello 1 2018-07-28 20:24:11.511604"}
receive from server:{"test": "hello 2 2018-07-28 20:24:11.612339"}
receive from server:{"test": "hello 3 2018-07-28 20:24:11.713062"}
receive from server:{"test": "hello 4 2018-07-28 20:24:11.813771"}
receive from server:{"test": "hello 5 2018-07-28 20:24:11.914492"}
receive from server:{"test": "hello 6 2018-07-28 20:24:12.015099"}
receive from server:{"test": "hello 7 2018-07-28 20:24:12.115936"}
receive from server:{"test": "hello 8 2018-07-28 20:24:12.216658"}
receive from server:{"test": "hello 9 2018-07-28 20:24:12.317399"}
3 client.html
<html>
<head>
<meta charset="utf-8">
<title>django-websockettitle>
<script src="jquery-1.8.3.min.js">script>
<script type="text/javascript">
$(function () {
$('#connect_websocket').click(function () {
if (window.s) {
window.s.close();
}
/*创建socket连接*/
var socket = new WebSocket("ws://localhost:8000");
socket.onopen = function () {
console.log('WebSocket open');//成功连接上Websocket
};
socket.onmessage = function (e) {
console.log('message: ' + e.data);//打印出服务端返回过来的数据
var d= $.parseJSON(e.data);
$('#messagecontainer').prepend(''
+ d.test + '');
};
if (socket.readyState == WebSocket.OPEN) socket.onopen();
window.s = socket;
});
$('#send_message').click(function () {
//如果未连接到websocket
if (!window.s) {
alert("websocket未连接.");
} else {
window.s.send($('#message').val());//通过websocket发送数据
}
});
$('#close_websocket').click(function () {
if (window.s) {
window.s.close();//关闭websocket
console.log('websocket已关闭');
}
});
});
script>
head>
<body>
<br>
<input type="text" id="message" value="开始..."/>
<button type="button" id="connect_websocket">连接 websocketbutton>
<button type="button" id="send_message">发送 messagebutton>
<button type="button" id="close_websocket">关闭 websocketbutton>
<div id="messagecontainer">
div>
body>
html>
run client.html
打开浏览器输入地址:file:///home/huang/Practise/demo1/client.html
输入 :你好,点击连接,再点击发送,开始推送:
output to server
A new client: 你好
send 你好 0 2018-07-28 20:38:34.384413
send 你好 1 2018-07-28 20:38:34.485158
send 你好 2 2018-07-28 20:38:34.585793
send 你好 3 2018-07-28 20:38:34.686401
send 你好 4 2018-07-28 20:38:34.787105
send 你好 5 2018-07-28 20:38:34.887769
send 你好 6 2018-07-28 20:38:34.988483
send 你好 7 2018-07-28 20:38:35.089176
send 你好 8 2018-07-28 20:38:35.189867
send 你好 9 2018-07-28 20:38:35.290481
output to client.html
你好 9 2018-07-28 20:38:35.290481
你好 8 2018-07-28 20:38:35.189867
你好 7 2018-07-28 20:38:35.089176
你好 6 2018-07-28 20:38:34.988483
你好 5 2018-07-28 20:38:34.887769
你好 4 2018-07-28 20:38:34.787105
你好 3 2018-07-28 20:38:34.686401
你好 2 2018-07-28 20:38:34.585793
你好 1 2018-07-28 20:38:34.485158
你好 0 2018-07-28 20:38:34.384413
1、web_server.py
import json
import time
import random
import datetime
import asyncio
import websockets
async def echo2(websocket, path):
message = await websocket.recv()
await websocket.send(message)
@asyncio.coroutine
def echo(websocket, path):
message = yield from websocket.recv()
print('recv', message)
dt = datetime.datetime.now()
cc = 1000
for i in range(1000):
dt2 = str(dt + datetime.timedelta(minutes=i))[11:19]
y = [cc + random.randint(-80, 100) for i in range(4)]
v = []
mi = min(y)
ma = max(y)
y.remove(mi)
y.remove(ma)
y = [y[0], y[1], mi, ma]
cc = y[2] if y[2] > 900 else 1000
s = {'datetime': dt2, 'topic': 'bar','open':y[0],'close':y[1],'high':y[2],'low':y[3]}
s = json.dumps(s)#.encode()
#print(s)
# request.websocket.send(s)
yield from websocket.send(s)
v = random.randint(0,5)
if v in (3,4):
v = 'SELL' if v==4 else 'BULL' # 卖出、买入
s = {'topic':'trade','trading_dt':dt2,'price':y[1],'side':v}
print(s)
s = json.dumps(s)#.encode()
# request.websocket.send(s)
yield from websocket.send(s)
time.sleep(0.5) # 间隔0.5秒
start_server = websockets.serve(echo, 'localhost', 8000)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
2 web_client.html
<html>
<head>
<meta charset="utf-8">
<title>django-websockettitle>
<script type="text/javascript" src="jquery-1.8.3.min.js">script>
<script type="text/javascript" src="echarts.min.js">script>
head>
<body>
<br>
<input type="text" id="message" value="200"/>
<button type="button" id="connect_websocket">连接button>
<button type="button" id="send_message">开始画图button>
<button type="button" id="close_ht">暂停画图button>
<button type="button" id="close_websocket">关闭接收数据button>
<div id="messagecontainer">
div>
<div id="main" style="width: auto;height: 800px;" align="center">div>
<script type="text/javascript">
var myChart = echarts.init(document.getElementById('main'));
var bs = new Array();
var xzs = new Array();
option = {
title : {
text: '回测',
subtext: 'K线'
},
tooltip : {
trigger: 'axis'
},
legend: {
data:['回测','卖出','买入']
},
toolbox: {
show : true,
feature : {
mark : {show: true},
dataView : {show: true, readOnly: false},
restore : {show: true},
saveAsImage : {show: true}
}
},
dataZoom : {
show : true,
realtime: true,
start : 50,
end : 100
},
xAxis : [
{
type : 'category',
boundaryGap : true,
data : [
]
}
],
yAxis : [
{
type : 'value',
scale:true,
splitNumber: 5,
boundaryGap: [0.05, 0.05]
}
],
series : [
{
name:'回测',
type:'k',
data:[ // 开盘,收盘,最低,最高
]
},{
name:'卖出',
type:'scatter',
symbol: 'arrow',//'star3',
symbolSize: 12,
smooth:true,
symbolRotate:180,
itemStyle:{
//symbolRotate:-90,
normal: { color:function(p){
return bs[p.name];
}
}
},
data: []
},{
name:'买入',
type:'scatter',
symbol: 'arrow',//'star3',
symbolSize: 12,
smooth:true,
symbolRotate:0,
itemStyle:{
//symbolRotate:-90,
normal: { color:function(p){
return bs[p.name];
}
}
},
data: []
}
]
};
stringToDate = function(dateStr,separator){
if(!separator){
separator="-";
}
var dateArr = dateStr.split(separator);
var year = parseInt(dateArr[0]);
var month;
//处理月份为04这样的情况
if(dateArr[1].indexOf("0") == 0){
month = parseInt(dateArr[1].substring(1));
}else{
month = parseInt(dateArr[1]);
}
var day = parseInt(dateArr[2]);
var date = new Date(year,month -1,day);
return date;
}
var k_x = new Array();
var k_y = new Array();
var y_x = new Array();
var y_y = new Array();
var y_y2 = new Array();
var is_huatu = true;
var size = $('#message').val()-0;
//myChart.setOption(option);
function timeTicket(x,y,type,side){
// 动态数据接口 addData
// lastIndex += 1;
// var len2 = option.series[0].data.length;
// var d = option.xAxis[0].data[len2-1];
// d = stringToDate(d,'/');
// d.setDate(d.getDate()+1);
// d = d.getFullYear()+'/'+(d.getMonth()+1)+'/'+d.getDate();
if(type=='k'){
var ind = k_x.indexOf(x);
if(ind<0){
k_x.push(x);
k_y.push(y);
y_y.push('');
y_y2.push('');
}else{
k_y[ind] = y;
}
if(is_huatu){
option.xAxis[0].data=k_x.slice(-size);
option.series[0].data=k_y.slice(-size);
option.series[1].data=y_y.slice(-size);
option.series[2].data=y_y2.slice(-size);
//option.series[1].symbolRotate=y_y.slice(-size);
myChart.setOption(option);
}
}else if(type=='y'){
var ind = k_x.indexOf(x);
if(ind<0){
k_x.push(x);
k_y.push(k_y[k_y.length-1]);
if(side=='SELL'){
y_y.push(y);
y_y2.push('')
}else{
y_y.push('');
y_y2.push(y)
}
}else{
//y_y[ind] = y;
if(side=='SELL'){
y_y[ind] = y;
}else{
y_y2[ind] = y;
}
}
if(is_huatu){
option.xAxis[0].data=k_x.slice(-size);
option.series[0].data=k_y.slice(-size);
option.series[1].data=y_y.slice(-size);
option.series[2].data=y_y2.slice(-size);
myChart.setOption(option);
}
}else{
option.xAxis[0].data=k_x.slice(-size);
option.series[0].data=k_y.slice(-size);
option.series[1].data=y_y.slice(-size);
option.series[2].data=y_y2.slice(-size);
myChart.setOption(option);
}
/*myChart.addData([
[
0, // 系列索引
option.series[0].data[lastIndex%len], // 新增数据
false, // 新增数据是否从队列头部插入
false, // 是否增加队列长度,false则自定删除原有数据,队头插入删队尾,队尾插入删队头
d //option.xAxis[0].data[lastIndex%len]
]
]);*/
}
$(function () {
function manages(info){
if (window.s) {
window.s.close();
}
/*创建socket连接*/
var url = "ws://localhost:8000"; // 连接地址
var socket = new WebSocket(url); //window.location.host
socket.onopen = function () {
console.log('WebSocket open');//成功连接上Websocket
if(info) alert('WebSocket open');
};
var x=null,y=null;
socket.onmessage = function (e) {
console.log('message: ' + e.data);//打印出服务端返回过来的数据
var d= $.parseJSON(e.data);
if(d.topic=='bar'){
x = d.datetime;
y=[d.open,d.close,d.high,d.low]
timeTicket(x,y,'k','');
}else if(d.topic=='trade'){
x = d.trading_dt;
y = d.price;
//bs = d.bs;
if(d.side=='SELL'){
bs[x]='green';
}else{
bs[x]='red';
}
timeTicket(x,y,'y',d.side);
}
};
// Call onopen directly if socket is already open
if (socket.readyState == WebSocket.OPEN) socket.onopen();
window.s = socket;
}
manages(false);
$('#connect_websocket').click(function () {
manages(true);
});
$('#send_message').click(function () {
//如果未连接到websocket
is_huatu = true;
if (!window.s) {
alert("websocket未连接.");
} else {
window.s.send($('#message').val());//通过websocket发送数据
}
});
$('#close_websocket').click(function () {
if (window.s) {
window.s.close();//关闭websocket
console.log('websocket已关闭');
}
});
$('#close_ht').click(function () {
is_huatu = false;
size = $('#message').val()-0;
timeTicket('','','','');
});
});
//var t=setInterval("timeTicket()",100);
script>
body>
html>
3 执行
1、python web_server.py
2、浏览器打开:web_client.html,点击开始画图
服务端输出结果:
D:\tools>python server_web.py
recv 200
{'topic': 'trade', 'trading_dt': '18:58:22', 'price': 882, 'side': 'BULL'}
{'topic': 'trade', 'trading_dt': '18:59:22', 'price': 1032, 'side': 'BULL'}
{'topic': 'trade', 'trading_dt': '19:01:22', 'price': 856, 'side': 'BULL'}
。。。。。。