20-2 樹莓派搭建服務器 Tornado Web服務器

Drive.google.com/drive/folders/1ahbeoEHkjxoo4NV1wReOmpoRWbl448z-javascript

 

1.Tornado簡介css

Tornado一款使用 Python 編寫的,相對簡單的 非阻塞式 Web 服務器,它是非阻塞式服務器,並且速度至關快。得利於其 非阻塞的方式和對 epoll 的運用,Tornado 每秒能夠處理數以千計的鏈接,所以 Tornado 是實時 Web 服務的一個 理想框架。html

官方網站:http://www.tornadoweb.cn前端

官方文檔:http://www.tornadoweb.cn/documentationjava

整個文檔就一個網頁,把http服務器經常使用的功能都講述了一遍,若是有編程基礎,應該很快就能上手。python

2.Tornado安裝jquery

方式1:pip 安裝:
sudo pip install tornadoweb


方式2:源代碼安裝:
wget https://pypi.python.org/packages/source/t/tornado/tornado-4.3.tar.gz
tar xvzf tornado-4.3.tar.gz
cd tornado-4.3
python setup.py build
sudo python setup.py installajax

 

2、基本原理shell

 

借用Tornado官方的Hello World例子:

import tornado.ioloop
import tornado.web
 
class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")
 
application = tornado.web.Application([
    (r"/", MainHandler),
])
 
if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

  

大體的思路是:經過Tornado開啓http端口偵聽,預設好路由規則,當有請求符合路由規則時,調用對應的Handler進行處理,這也是大部分Web服務器的處理方式。支持get和post請求。

 

擴展一下,利用Tornado搭建一個http服務器,上面放一個網頁,網頁端傳入須要控制的GPIO針腳編號和狀態,服務器端接收到傳入的參數,作相應的處理,便可實現控制GPIO針腳電平的輸出了。



3、實現步驟

1.前端html頁面

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>樹莓派Web控制中心</title>
    <script src="static/js/jquery-3.2.1.min.js" type="text/javascript"></script>
    <script src="static/js/bootstrap.min.js" type="text/javascript"></script>
    <link href="static/css/bootstrap.css" rel="stylesheet" type="text/css" />
    <link href="static/css/font-awesome-4.7.0/css/font-awesome.min.css" rel="stylesheet"
        type="text/css" />
    <style type="text/css">
        .page-header { margin: 20px 0; border-bottom: 1px solid #eee; padding-bottom: 0; text-align: center; }
        .btn-item { text-align: center; }
        i { margin-right: 3px; display: inline-block; }
        h1 { text-align: center; }
        .tip { font-weight: bold; color: black; }
        .lead { font-size: small; }
        .gpio-item { text-align: center; }
        .btn-gnd, .btn-gpio { padding: 10px 5px; margin-bottom: 5px; width: 100%; font-size: small; }
        .gpio .row { margin-top: 5px; }
    </style>
</head>
<body>
    <div class="container">
        <div class="page-header">
            <h3>
                樹莓派Web控制中心</h3>
            <p class="lead">
                用於控制鏈接到樹莓派的各類傳感器
            </p>
        </div>
        <div class="panel panel-default">
            <div class="panel-heading">
                設備</div>
            <div class="panel-body">
                <div class="row">
                    <div class="col-xs-3 btn-item">
                    </div>
                    <div class="col-xs-3 btn-item">
                        <a class="btn btn-danger btn-trigger"><i class="fa fa-power-off"></i>關機</a>
                    </div>
                    <div class="col-xs-3 btn-item">
                        <a class="btn btn-primary btn-trigger"><i class="fa fa-refresh"></i>重啓</a>
                    </div>
                    <div class="col-xs-3 btn-item">
                    </div>
                    <script type="text/javascript">
                        var url = "/";
                        $(function () { 
                            $(".btn-trigger").click(function () {
                                var text = $(this).text().replace(/ /g, "").replace(/\n/g, "").replace(/\r/g, "").replace(/\t/g, "");
                                var cmd = "";
                                switch (text) {
                                    case "關機":
                                        cmd = "sudo shutdown -h now";
                                        break;
                                    case "重啓":
                                        cmd = "sudo reboot";
                                        break;
                                }
                                if (confirm("肯定要執行該命令嗎?")) {
                                    $.ajax({
                                        type: "POST",
                                        url: url,
                                        data: {
                                            action: "run-shell-cmd",
                                            cmd: cmd
                                        },
                                        success: function (result) {
                                            //$(".tip").html(result);
                                        }
                                    });
                                }
                            });
                        });
                    </script>
                </div>
            </div>
        </div>
        <div class="panel panel-default">
            <div class="panel-heading">
                GPIO (藍色->低電平,紅色->高電平)</div>
            <div class="panel-body gpio">
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        左側
                    </div>
                    <div class="col-xs-6 gpio-item">
                        右側
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (9) 左05</button>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (6) 右03</button>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="17">17 (11) 左06</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="18">18 (12) 右06</a>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="27">27 (13) 左07</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (14) 右07</button>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="22">22 (15) 左08</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="23">23 (16) 右08</a>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (25) 左13</button>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="24">24 (18) 右09</a>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="5">05 (29) 左15</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (20) 右10</button>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="6">06 (31) 左16</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="25">25 (22) 右11</a>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="13">13 (33) 左17</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (30) 右15</button>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="19">19 (35) 左18</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="12">12 (32) 右16</a>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="26">26 (37) 左19</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (34) 右17</button>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="20">20 (37) 右19</a>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="16">16 (36) 右18</a>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-6 gpio-item">
                        <button disabled="disabled" class="btn btn-info btn-gnd">
                            GND (39) 右20</button>
                    </div>
                    <div class="col-xs-6 gpio-item">
                        <a class="btn btn-primary btn-gpio" pin="21">21 (40) 右20</a>
                    </div>
                </div>
                <script type="text/javascript">
                    $(function () {
                        $(".btn-gpio").click(function () {
                            var gpio = $(this).attr("pin");
                            if ($(this).hasClass("btn-danger")) {
                                $(this).removeClass("btn-danger").addClass("btn-primary");
                            } else {
                                $(this).removeClass("btn-primary").addClass("btn-danger");
                            }
                            var status = $(this).hasClass("btn-danger") ? 1 : 0;
                            $.ajax({
                                type: "POST",
                                url: url,
                                data: {
                                    action: "set-gpio-pin",
                                    pin: gpio,
                                    status: status
                                },
                                success: function (result) {
                                    //$(".tip").html(result);
                                }
                            });
 
                        });
                    })
                </script>
            </div>
        </div>
    </div>
</body>
</html>


  

2.Python腳本

#coding: utf8
import sys
import RPi.GPIO as GPIO
import time
import os
import tornado.ioloop
import tornado.web
import tornado.httpserver
import tornado.options
from tornado.options import define,options
 
#初始化
def init():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BCM)
 
#設置GPIO針腳電平輸出
def SetPinStatus(pin,status):
    GPIO.cleanup(int(pin))
    GPIO.setup(int(pin),GPIO.OUT)
    if(int(status)==0):
        GPIO.output(int(pin),GPIO.LOW)
    else:
        GPIO.output(int(pin),GPIO.HIGH)
    
#路由處理	
class IndexHandler(tornado.web.RequestHandler):
        def get(self):
                self.render("index.html")
        def post(self):
                init()
		action=self.get_argument('action')
		#設置GPIO針腳電平輸出
		if(action=="set-gpio-pin"):
		    pin = self.get_argument('pin')
                    status = self.get_argument('status')
		    SetPinStatus(pin,status)
		    self.write("true")
		#執行shell腳本,如:關機,重啓
		elif(action=="run-shell-cmd"): 
		    cmd = self.get_argument('cmd')
                    os.system(cmd)					
                
if __name__ == '__main__':
    #控制檯輸出響應結果,正式環境能夠不開啓
    #tornado.options.parse_command_line()
    settings={
        "static_path":os.path.join(os.path.dirname(__file__),"static")
        }
    app = tornado.web.Application(
        handlers=[
            (r"/",IndexHandler),
            (r"(apple-touch-icon\.png)",tornado.web.StaticFileHandler,dict(path=settings['static_path']))
        ],**settings)
    
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(8020)
    tornado.ioloop.IOLoop.instance().start()
    GPIO.cleanup()

  

3.目錄結構

 

4.部署調試

在終端輸入:python /var/www/html/pi/gpio/gpio.py (路徑爲我樹莓派中文件路徑,實際路徑以你本身的環境爲準。)

若是終端沒報錯,此時打開瀏覽器,輸入地址:http://localhost:8020 便可訪問到頁面,8020是python腳本中偵聽的端口,你能夠自行設置。

5.運行結果

 

6.源碼下載

http://download.csdn.net/download/a497785609/9990088

相關文章
相關標籤/搜索