评论

小程序用wx.request()构成长轮询服务器数据库的方法

介绍了小程序用wx.request()构成长轮询服务器数据库的方法,且与使用云开发环境做了比较

任务举例:我的轻量服务器上有一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元!逼上梁山,买了一个轻量服务器,

      从头学习后端开发知识。现在,我的小程序“桥牌比赛”成功地转移到了自己的服务

      器上,没有了这可怕的消费,还大大提高了速度:原本用云开发环境网速几百毫秒,

      现在自己的服务器网速几十毫秒!




        

最后一次编辑于  2023-06-11  
点赞 0
收藏
评论

2 个评论

  • nono
    nono
    2023-02-06

    敬请赐教

    2023-02-06
    赞同
    回复
  • 鲤子
    鲤子
    2023-02-06

    这用socket不简单得多

    2023-02-06
    赞同
    回复 8
    • nono
      nono
      2023-02-06
      敬请赐教
      2023-02-06
      回复
    • nono
      nono
      2023-02-07
      我在服务器端基本上还是小白,只是捞到了wx.request()这根救命稻草。php 程序也是照猫画虎学来的,里边有些语句什么意思也没搞明白。Websocket大名虽是网上到处都是、如雷贯耳,但找不到小白能模仿的例子。因此真诚向您请教了!
      2023-02-07
      回复
    • 鲤子
      鲤子
      2023-04-18回复nono
      啊这个需要后端的能力,首先如果你是使用php作为后端语言,你可以使用php的socket,像workman这种框架。
      2023-04-18
      回复
    • nono
      nono
      2023-06-09回复鲤子
      还是没有门路,望能具体指导
      2023-06-09
      回复
    • 鲤子
      鲤子
      2023-06-13回复nono
      就是websocket通信
      2023-06-13
      回复
    查看更多(3)
登录 后发表内容