加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

20-2 树莓派搭建服务器 Tornado Web服务器

发布时间:2020-12-20 12:53:37 所属栏目:Python 来源:网络整理
导读:Drive.google.com/drive/folders/1ahbeoEHkjxoo4NV1wReOmpoRWbl448z- ? 1.Tornado简介 Tornado一款使用 Python 编写的,相对简单的 非阻塞式 Web 服务器,它是非阻塞式服务器,而且速度相当快。得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处

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

?

1.Tornado简介

Tornado一款使用 Python 编写的,相对简单的 非阻塞式 Web 服务器,它是非阻塞式服务器,而且速度相当快。得利于其 非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以千计的连接,因此 Tornado 是实时 Web 服务的一个 理想框架。

官方网站:http://www.tornadoweb.cn

官方文档:http://www.tornadoweb.cn/documentation

整个文档就一个网页,把http服务器常用的功能都讲述了一遍,如果有编程基础,应该很快就能上手。

2.Tornado安装

方式1:pip 安装:
sudo pip install tornado


方式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 install

?

二、基本原理

?

借用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针脚电平的输出了。



三、实现步骤

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",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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读