搞了几天,顺便把代码贴这里,需要的 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 发来的数据显示出来。
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='https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/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()