Python Websocket

1 django dwebsocket 模块

一、创建项目(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 文件夹

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>django-websocket</title>
    {% load staticfiles %}
    <script src="{% static 'jquery-1.8.3.min.js' %}"></script>
    <script type="text/javascript">//<![CDATA[
    $(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('<p>' + e.data + '</p>');
            };
            // 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('<p>' + d.test + '</p>');
            };
            // 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">连接 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>
{{init}}
</body>
</html>

六、开始执行:
这两句在这里不是必要的
python manage.py makemigrations
python manage.py migrate

运行服务器
python manage.py runserver

七、访问:
打开浏览器输入地址:http://localhost:8000/index/
我们将看到页面:
img1

点击连接,再点击发送,开始推送:
这里写图片描述

2 websockets 模块

**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-websocket</title>
    <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('<p>' + d.test + '</p>');
            };
            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">连接 websocket</button>
<button type="button" id="send_message">发送 message</button>
<button type="button" id="close_websocket">关闭 websocket</button>

<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

3 websockets 模块模拟动态推送K线图数据回测

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

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>django-websocket</title>
    <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'}
。。。。。。

浏览器输出结果:
这里写图片描述
注:此代码只是个人根据当时的环境满足了当时的需求,记录下来用做后续参考!如有问题,请检查软硬件环境是否一致,由于时间精力有限,大部分未做详细环境描述。

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值