esp8266远程控制电风扇之心跳包

在昨天完成了esp8266开发板对电风扇的远程控制后,发现了一个非常离谱的问题

在开发板和控制端连接服务器后,可以通过控制端向服务器端发送指令并由服务器端转发给开发板,以达到远程控制开发板的功能。

但在开发板连接服务器后,长期不对开发板进行控制就会出现服务器转发指令失败的情况。

最开始以为是开发板的代码出现了问题,当对代码多次调试后并没有发现BUG,于是在网上了解到TCP长连接(保持长时间的通信)需要定时发送心跳包(具体数据内容没有限制)。

心跳包的作用就是隔一段时间给服务器发送一个信号,信号内容无所谓,可以理解为客户端告诉服务器“我还活着”,如果长时间不向服务器发送心跳包,路由器会认为客户端“死”了,就会断开连接。

具体心跳包内容参考:TCP之心跳包实现思路 - 程序诗人 - 博客园 (cnblogs.com)

了解了问题后,对开发板程序进行修改:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
/*****************网络设置项 *****************/
const char *STAssid ="fan"; //需要连接路由器的名称
const char *STApassword="zxf834580866"; //路由器的密码
const char *host= "81.70.254.76"; //外网服务器ip
const int httpPort = 60000; //外网服务器端口
WiFiClient client; //声明客户端对象
bool is=0; //用来做连接到服务器后,仅发送一次问候语
int led=14; //灯io,D5
unsigned long time1;
unsigned long time2;
void setup() {
Serial.begin(115200);
Serial.println("");
pinMode(14,OUTPUT);
digitalWrite(14,1);
WiFi.mode(WIFI_STA); //设置为STA模式
WiFi.begin(STAssid, STApassword); //配置连接信息,开始连接
//运行自定义函数,在未连接到路由器的过程中,打印输出......,直到连接成功
gotoWifi();
Serial.println("连接路由器成功");
//此时已经连接到路由器,可以开始连接远程服务器
lianjie();
time1=millis();
time2=millis();
while(true){

if (WiFi.status() != WL_CONNECTED) {
WiFi.disconnect();
WiFi.begin(STAssid, STApassword);
gotoWifi();
}
else{
if (!client.connected()) { //如果没有连接到服务器
is=0;
lianjie();
return;
}
else{ //否则,就是连接到服务器
if(is==0){
client.print("hello,server");
is=1;
}
}
}
Tcp_Handler(Read_Tcp()); //读取服务器信息,并处理
delay(2);
time2=millis();
if(time2-time1>36000)//当时间间隔大于36秒时,发送心跳包
{
time1=millis();
client.print("1");
Serial.println("心跳");
}
//Serial.println(client.connected());
}
}

void loop() {
/****************检测WiFi连接状态****************/

}
//读取服务器信息,返回String类型
String Read_Tcp(){
String data = "";
while (client.available() > 0){
data += char(client.read());
delay(2);
}
return data;
}
//处理服务器信息
void Tcp_Handler(String data){
if(data!=""){
Serial.print("收到服务器信息:");
Serial.println(data);
if(data=="open"){
digitalWrite(14,0);
client.print("open led");
}
else if(data=="close"){
digitalWrite(14,1);
client.print("close led");
}
}
}
//连接路由器
void gotoWifi(){
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
}
//连接服务器
void lianjie() {
Serial.println("开始连接服务器");
client.connect(host, httpPort);
delay(1000);
}

这样就解决了开发板与服务器之间出现断开连接的情况。

而客户端方面则实现起来更好操作

易语言可设置时钟,每36秒发送一次数据包。

手机客户端可在服务器连接成功后加入以下代码进行心跳包发送

Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
try{
os.write("1".getBytes());
os.flush();
}catch (Exception e){
Log.e("erro",String.valueOf(e));
}
}
},
36000);


目前远程控制电风扇的控制端有:电脑端(易语言)

手机端(Android studio)

网页端(PHP)

 
感谢小艾同学提供Android 端和网页端技术支持

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注