背景

昨天完成了手机客户端远程控制树莓派上LED亮灭的实验(点击回顾,今天来做一些拓展,从客户端远程一键控制与树莓派处于同一内网的服务器的服务开关。

目标要求

在任意联网的客户端点击“关闭”链接,指定服务器的nginx服务关闭。

制作思路

只要把“开关LED”这一操作,转换成“执行开关服务”即可。而“开关服务”可以直接使用ssh命令。

软件配置

云端的配置与原来相同,只需要修改树莓派的配置。

树莓派配置

接收串口数据并执行shell脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//to-shutdown.cpp

#include<iostream>
#include<wiringPi.h>
#include<wiringSerial.h>

#define LED 1

using namespace std;

int main()
{
int MySerial;
int flag=0;

pinMode(LED, OUTPUT);
if (wiringPiSetup()<0)
{
cout << "Setup Failed!\n";
exit(0);
}

if ((MySerial=serialOpen("/dev/ttyS0", 115200))<0)
{
cout << "Serial Failed!\n";
exit(0);
}

while (1)
{
if (serialDataAvail(MySerial)>0)
{
char ch=serialGetchar(MySerial);
cout << ch << endl;
int val=ch-48;
if (flag != val)
{
flag=val;
if (val==0)
system("sh turn-off.sh");
if (val==1)
system("sh turn-on.sh");
digitalWrite(LED, val);
}

}
}

serialClose(MySerial);

return 0;
}

这里,如果接收到0,则关闭服务,如果接收到1,则开启服务。为了避免多次重复开关,设置了一个flag变量用于判断。

至于ssh控制服务器的脚本,本人查阅资料后决定采用sshpass,这个插件可以在ssh命令中携带密码。当然,如果有密钥对的话,就更加简单了。

1
2
3
4
#!/bin/bash
#turn-off.sh

sshpass -p '<password>' ssh -p 22 root@192.168.27.20 service nginx stop
1
2
3
4
#!/bin/bash
#turn-on.sh

sshpass -p '<password>' ssh -p 22 root@192.168.27.20 service nginx start

实际测试

将编译后的to-shutdown.cppturn-off.shturn-on.sh放在同一目录内,运行。

实际效果如图,这里为了便于演示,用PC端模拟手机操作。
效果动画

可以看到,关闭命令发送后几秒内,web服务即停止。开启命令发送后,web服务也迅速恢复。