zoukankan      html  css  js  c++  java
  • python 搭建 websocket server 发送 sensor 数据

    搞了几天,顺便把代码贴这里,需要的 python 包:

    gevent,gevent-websocket,bottle,wiringpi-python

    简单说明:

    - gevent 提供了支持 concurrent,以及 concurrent 下的 socket 操作。注意,引入 monkey 后,socket 就是 genvent 封装过的了,不再是系统原生 socket。

    - 连接到 /ws 后,链接为长链接,使用 gevent.Timeout() 提供的 alarm 来周期执行 sensor 读操作,并将读到的数据发送给 client。

    - 浏览器端,直接访问根目录,返回是一个 web client,提供了一个 textarea,将 server 发来的数据显示出来。

    - 浏览器端,没有写发送,需要的话可以按 F12 在 console 里面,直接调用 ws.send('your_message') 来想服务器发送。

    from bottle import route, run, request, abort, Bottle, static_file
    from gevent import monkey; monkey.patch_all()
    from gevent import sleep, Timeout
    
    import wiringpi
    import serial
    
    app = Bottle()
    
    host = '0.0.0.0'
    port = 8080
    
    SensorData = ''
    
    fdI2c = wiringpi.wiringPiI2CSetup(0x40)
    ser = serial.Serial("/dev/ttyUSB0", 9600, timeout = 0.1)
    
    def readSensor():
        global SensorData
        
        serBuffer = ser.readline().rstrip()
        if len(serBuffer) == 0:
            serBuffer = "0";
    
        strength = wiringpi.wiringPiI2CReadReg16(fdI2c, 0x1c);
        position = wiringpi.wiringPiI2CReadReg16(fdI2c, 0x0c);
        angle = wiringpi.wiringPiI2CReadReg16(fdI2c, 0x0e);
        
        SensorData = serBuffer + ":" 
                     + str(strength) + ":" 
                     + str(position) + ":" 
                     + str(angle);
    
    @app.route('/ws')
    def handle_websocket():
        wsock = request.environ.get('wsgi.websocket')
        if not wsock:
            abort(400, 'Expected WebSocket request.')
        while True:
            try:
                global SensorData
                with Timeout(0.5, False) as timeout:
                    message = wsock.receive()
                if not message:
                    readSensor()
                    message = SensorData
    
                wsock.send("%r" % message)
    
                message = u''
            except WebSocketError:
                break
    
    @app.route('/')
    def send_index():
        return """<html>
    <head>
      <script type='application/javascript' src='http://libs.baidu.com/jquery/2.0.0/jquery.min.js'></script>
      <script type="text/javascript">
        var ws = new WebSocket("ws://%(host)s/ws");
        ws.onopen = function() {
            ws.send("Hello, world");
        };
        ws.onmessage = function (evt) {
            $('#chat').val($('#chat').val() + evt.data + '\n');
        };
      </script>
    </head>
    <body>
    <form action='#' id='chatform' method='get'>
        <textarea id='chat' cols='100' rows='20'></textarea>
    </form>
    
    </body>
    </html>"""%{'host':request.headers.get('Host')}
    
    from gevent.pywsgi import WSGIServer
    from geventwebsocket.handler import WebSocketHandler
    from geventwebsocket import WebSocketError
    
    server = WSGIServer((host, port), app, handler_class=WebSocketHandler)
    
    print "access @ http://%s:%s" % (host, port)
    server.serve_forever()

     上面的 timeout 函数是为了给 wsock.receive() 提供充足的时间,使其在这段时间内一直等待接收状态。

    另外可以用 sleep() (注意, sleep 是从 gevent 引入的,并不是 time 那个 sleep)来交出 gevent 控制权,让其它协程获得 CPU。

  • 相关阅读:
    python字典
    python元组
    python list列表
    deepin常用操作
    Be a child.Be a man...
    “夹心阶层”——面对高昂的房价,要面对现实,广州,除了劳动力便宜,什么都贵。
    男人一生中16件事情(转载)
    被老板臭骂了一顿,但受益匪浅。
    陪伴
    高品质生活
  • 原文地址:https://www.cnblogs.com/pied/p/11972095.html
Copyright © 2011-2022 走看看