任务举例:我的轻量服务器上有一MYSQL数据库,其中有一表rooms,表中有一字段cdname(字符型), 当其内容有变化时,小程序端要即时作出反应。
完成方法:
1.小程序端代码如下:(每60秒启动一次查询)
Page({
data: {
CDNAME:"",
CDNAMEb:"",
}
onLoad:function(){
this.reFresh()//启动长轮询
},
reFresh:function(){//长轮询服务器数据库rooms
var that=this
//启动服务器www根上roomsLC.php程序
wx.request({url: 'https://******.***/roomsLC.php' ,
data:{id:1,
CDNAME:that.data.CDNAMEb, //向服务器roomsLC.php程序发出比较基准
},
success:function(res){
that.data.CDNAMEb=res.data.cdname
......//(相应的响应程序,处理服务器发回的res.data.cdname)
var timerName=setTimeout(function(){
that.reFresh()
clearTimeout(timerName)
},1000)//1000毫秒,为响应程序留的时间
},
fail: function(){
console.log('超时')//App.json中默认超时时间为60秒
that.reFresh()
}
})
}
})
注:为了各个场景的兼容性,用complete代替fail!!!(2023.6.11增)
2.服务器www根上roomsLC.php程序代码:(收到查询请求后每100毫秒查询一次数据库,若有变化往小程序发回结果)
<?php
ignore_user_abort();//即使小程序关闭php程序也照样执行
set_time_limit(0);//php默认的执行时间是30秒,0为无限长。
$id =$_GET["id"]; //接收参数
$CDNAME =$_GET["CDNAME"];
$L0="cdname,".$CDNAME;//比较基准
class rooms{
public $cdname;
}
function roomsC($id){
$hostname_conn = "localhost";
$database_conn = "****";//自己建数据库名
$username_conn = "***";//用户名
$password_conn = "######";//密码
//连接MYSQL数据库
$conn = mysqli_connect($hostname_conn, $username_conn,
$password_conn,$database_conn)or trigger_error
(mysqli_error(),E_USER_ERROR);
if(!$conn){ echo "连接不成功!";}
$sql = "SELECT *FROM rooms";
mysqli_query($conn, "set names 'utf8'");
$result = mysqli_query($conn, $sql);
$data = array();
if (mysqli_num_rows($result)>0) {
while($row = mysqli_fetch_assoc($result)) {
$rooms=new rooms();
$rooms->cdname=$row["cdname"];
$data[] = $rooms;
}
$Return =$data[$id-1];//先不进行JSON转换
}
mysqli_free_result($result);//释放结果
mysqli_close($conn);//关闭数据库
return $Return;
};
$lable='';
do//轮询
{
$LL=roomsC($id);//查询得到的新值
foreach ($LL as $key => $value) {//将$LL变成字符串
$lin= $lin.$key.','.$value; }//$lin是临时变量
if(strcmp($lin,$L0)!=0)//将新值与原值比较
{echo json_encode($LL,JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT);
$lable='true';
}//有变化时返回变化值
$lin='';//清零 ,必须的!
usleep(100000); //每隔100毫秒查询一次(usleep单位是微秒)
} while ($lable!='true');
?>
附记:这是我的小程序“桥牌比赛”最主要的任务。以前我用的是腾讯的云开发环境,
我放在云数据库中的表rooms若有变化则可即时通知我的小程序(原理与代码不知),
我小程序端代码则非常简单:
Page({
data: {
watcher:'',
}
......
const db = wx.cloud.database({})
this.data.watcher = db.collection('rooms').where({_id:1}).watch({
onChange: function(snapshot) {
... snapshot.docChanges[0].doc.cdname ...//对其响应
} })
......
})
原本工作得很好,但好景不长,腾讯突然涨价,而且使用数据库的次数也不知是怎么
算的,结果四个人打30副牌近8万次需花费4-5元!逼上梁山,买了一个轻量服务器,
从头学习后端开发知识。现在,我的小程序“桥牌比赛”成功地转移到了自己的服务
器上,没有了这可怕的消费,还大大提高了速度:原本用云开发环境网速几百毫秒,
现在自己的服务器网速几十毫秒!
敬请赐教
这用socket不简单得多