美文网首页聊者说
微信小程序-局域网内UDP通信

微信小程序-局域网内UDP通信

作者: 聊者说 | 来源:发表于2020-09-29 17:41 被阅读0次

    微信小程序的API可以说是越来越强大了,UDP通信也有了。

    近期,有个项目可能要用到小程序,刚好提前研究学习调研,顺便写个简单例子总结一下。

    通信效果展示

    小程序端 QT端

    小程序UDP通信这一块可以说是很简单了就一个UDPSocket实例。然后bind()方法绑定端口,send()方法发送数据,close()方法关闭通信,onMessage()方法监听消息等等,具体可以去看文档。

    既然是通信,那么至少得有两个参与者,这里我以小程序为Server端,QT应用程序为Client端。

    小程序为Server端:

    固定IP:不定
    端口号:不定

    小程序UDP通信,Server端蛮简单:
    创建UDPSocket实例,bind()方法绑定端口,onListening()方法监听,onMessage()方法接收消息,send()方法发送数据,close()方法关闭通信,onMessage()方法监听消息等等,具体可以去看官方文档。

      initUdpSocket() {
        this.data.udpSocket = wx.createUDPSocket();
        if (this.data.udpSocket === null) {
          console.log('暂不支持')
          return ;
        }
    
        const locationPort = this.data.udpSocket.bind()
        this.setData({
          'locationUrl.port': locationPort
        })
    
        this.data.udpSocket.onListening(function(res){
          console.log('监听中Res ===' + res)
        })
    
        let that = this
        this.data.udpSocket.onMessage(function (res) {
          console.log('remoteInfo ===' + res.remoteInfo)
          console.log('remoteInfo.size ===' + res.remoteInfo.size)
          if (res.remoteInfo.size > 0) {
            console.log('UDP接收数据 ' + res.remoteInfo.size + ' 字节:' + JSON.stringify(res, null, '\t'))
      
            let unit8Arr = new Uint8Array(res.message);
            let encodedString = String.fromCharCode.apply(null, unit8Arr);
            let escStr = escape(encodedString);
            let decodedString = decodeURIComponent(escStr);
            
            console.log('str==='+decodedString)
            let list = that.data.messageList
            let obj = {
              text: decodedString,
              from: 1
            }
            list.push(obj)
            that.setData({
              messageList: list
            })
          }
        })
      },
    
    sendMessage() {
        if (this.data.mydata.isSend) {
          return ;
        }
        this.data.mydata.isSend = true
        let ip = this.data.mydata.remoteUrl.ip
        let port = this.data.mydata.remoteUrl.port
        let message = this.data.mydata.message
        if (message.trim() === '') {
          wx.showToast({
            title: '请输入内容',
          })
          this.data.mydata.isSend = false
          return ;
        }
    
        this.data.udpSocket.send({
          address: ip,
          port: port,
          message: message
        })
    
        this.data.mydata.isSend = false
        let list = this.data.messageList
        let obj = {
          text: message,
          from : 2
        }
        list.push(obj)
        this.setData({
          messageList : list
        })
      },
    

    QT应用程序为Client端:

    固定IP:如,192.168.1.103
    端口号:6510

    QT端UDP通信,Server也简单:

    创建QUdpSocket

    void AppUdp::createSocket()
    {
        if (mUdpSocket != nullptr)
        {
            delete mUdpSocket;
            mUdpSocket = nullptr;
        }
        mUdpSocket = new QUdpSocket();
    }
    
    

    绑定端口:6510

    void AppUdp::listen(unsigned short listenPort)
    {
        // udp端口监听(线程安全)
        if (listenPort != 0)
        {
            appConfig->clientPort = listenPort;
        }
    
        // signalListenSuccess信号返回监听结果,listenSuccess属性可获取
        emit signalSelfListenPort();
    }
    
    void AppUdp::slotSelfListenPort()
    {
        bool result = mUdpSocket->bind(QHostAddress::Any, appConfig->clientPort);
        this->setListenSuccess(result);
        if (result)
        {
            QLOG_INFO() << "bind success ======= Listen port:" + QString("%1").arg(appConfig->clientPort);
        }
        else
        {
            QLOG_FATAL() << "bind fail ======= Listen port:" + QString("%1").arg(appConfig->clientPort);
        }
    
        emit signalListenSuccess(result);
    }
    

    udp监听回调

    void AppUdp::slotUdpSocketReceive()
    {
        while (mUdpSocket->hasPendingDatagrams())
        {
            QHostAddress targetaddr;
            unsigned short targetPort;
            QByteArray datagram;
            datagram.resize(static_cast<int>(mUdpSocket->pendingDatagramSize()));
            mUdpSocket->readDatagram(datagram.data(), datagram.size(), &targetaddr, &targetPort);
            if (datagram.size() > 0)
            {
                emit signalUdpSocketReceiveData(targetaddr, targetPort, datagram);
            }
        }
    }
    

    QT端作了一个信息回馈,

    void AppUdpClientServer::slotSelfWriteControl(const QByteArray data)
    {
        QHostAddress address;
        address.setAddress(appConfig->serverIp);
        qint64 result = mUdpSocket->writeDatagram(data, address, appConfig->serverPort);
    
        if (result == -1)
        {
            QLOG_WARN() << "Send ip=" << appConfig->serverIp << "Send port=" << appConfig->serverPort << " result=" << result
                        << " udpState=" << mUdpSocket->state();
    
            createSocket();
            result = mUdpSocket->writeDatagram(data, address, appConfig->serverPort);
            if (result == -1)
            {
                QLOG_FATAL() << "Send ip=" << appConfig->serverIp << "Send port=" << appConfig->serverPort << " result=" << result
                             << " udpState=" << mUdpSocket->state();
                emit signalUdpSocketError();
            }
        }
    }
    

    回馈前,需要在Client接收数据是解析,IP和端口号

    
    void AppUdpServerControl::slotClienttReceiveData(QHostAddress ipAddr, unsigned short port, QByteArray bytes)
    {
        QMutexLocker locker(m_mutex);
        QString qStrIpAddrTemp = ipAddr.toString();
        QString qStrIpAddr;
    
        int i = 0;
    
        // 填充ip地址
        for (i = 7; qStrIpAddrTemp[i] != '\0'; i++)
        {
            qStrIpAddr[i - 7] = qStrIpAddrTemp[i];
        }
    
        QLOG_INFO() << "Ip[" << qStrIpAddr << "]. ort[" << port << "]. Size[" << bytes.size() << "]." << endl;
        QString keyCmd                                 = QString(bytes);
        appUdpClientServer->getAppConfig()->serverIp   = qStrIpAddr;
        appUdpClientServer->getAppConfig()->serverPort = port;
    
        if ("1" == keyCmd)
        {
            // TODO 一键回原点
            motorSystem->getSystemMotor()->getParentBoard()->returnHome();
        }
        else if ("2" == keyCmd)
        {
            // TODO 单轴回原点
            motorSystem->getControl()->returnHome();
        }
        else if ("3" == keyCmd)
        {
            // TODO 下降5mm
            motorSystem->getControl()->moveByType(5);
            const QByteArray data = "中文zhongwen";
            appUdpClientServer->udpWriteData(data);
        }
    
        QLOG_INFO() << "keyCmd == " << keyCmd << "]." << endl;
    }
    
    

    感谢大家看完微信小程序UDP通信篇,更多精彩等待下次创作,你最大的支持就是:赞同+评论+赞赏+...,关注我

    另外,也欢迎大家关注我的个人公众号 “聊者说”。

    相关文章

      网友评论

        本文标题:微信小程序-局域网内UDP通信

        本文链接:https://www.haomeiwen.com/subject/vmekuktx.html