zoukankan      html  css  js  c++  java
  • 微信小程序UDP通信

    前言
    
    UDP通信分为单播 广播 组播,基础库2.7.0之后,小程序开始支持UDP通信,目前小程序只支持单播。
    小程序API
    
    小程序UDP通信这一块可以说是很简单了就一个UDPSocket实例。然后bind()方法绑定端口,send()方法发送数据,close()方法关闭通信,onMessage()方法监听消息等等,具体可以去看文档
    相关技术难点
    
    使用UDP通信时,如果是用于局域网内数据传输,这里有个难点就是,不知道本机及对应要通信设备在当前局域网内的ip及绑定的端口。如果是用于和服务器之间的数据传输的话,没想出具体应用场景...
    通信效果展示
    
    由于没有2台手机,所以用node.js代码充当了其中一台客户端,先看看客户端间通信截图。
    
    client1.png
    client2.png
    Node.js端代码
    
    通过dgram框架进行操作,这里由于演示,所以每次都简单地返回相同的数据。
    
    const dgram = require('dgram');
    const server = dgram.createSocket('udp4');
    server.on('close',()=>{
        console.log('socket已关闭');
    });
    server.on('error',(err)=>{
        console.log(err);
    });
    server.on('listening',()=>{
        console.log('socket正在监听中...');
    });
    server.on('message',(msg,rinfo)=>{
        console.log(`receive message from ${rinfo.address}:${rinfo.port}`);
        console.log(`message=${msg}`)
        server.send('收到你的信息了',rinfo.port,rinfo.address)
    });
    server.bind('8060');
    
    小程序端代码
    
    代码比较简单,唯一需要注意的是,接收到udp消息时,数据是ArrayBuffter格式的,需要转成string显示。(这部分代码在js代码最下方)
    
    // js代码
    // pages/welcome/welcome.js
    let util = require('../../utils/util.js')
    Page({
     udpSocket:null,
     /**
      * 页面的初始数据
      */
     data: {
       messageList:[]
     },
     mydata:{
       message:'',
       remoteUrl: {
         ip: '',
         port: -1
       },
       isSend:false
     },
     addMessage(event){
       console.log(event)
       this.mydata.message = event.detail.value
     },
     sendMessage(){
       if (this.mydata.isSend){
         return ;
       }
       this.mydata.isSend = true
       let ip = this.mydata.remoteUrl.ip
       let port = this.mydata.remoteUrl.port
       let message = this.mydata.message
       if(message.trim() === ''){
         wx.showToast({
           title: '请输入内容',
         })
         return ;
       }
       udpSocket.send({
         address: ip,
         port: port,
         message: message
       })
       this.mydata.isSend = false
       let list = this.data.messageList
       let obj = {
         text: message,
         from : 2
       }
       list.push(obj)
       this.setData({
         messageList : list
       })
     },
     /**
      * 生命周期函数--监听页面加载
      */
     onLoad: function (options) {
       this.initUdpSocket()
     },
     initUdpSocket(){
       udpSocket = wx.createUDPSocket();
       if(udpSocket === null){
         console.log('暂不支持')
         return ;
       }
       const locationPort = udpSocket.bind()
       this.setData({
         'locationUrl.port': locationPort
       })
       udpSocket.onListening(function(res){
         console.log('监听中...')
         console.log(res)
       })
       let that = this
       udpSocket.onMessage(function (res) {
         console.log(res)
         let str = util.newAb2Str(res.message)
         console.log('str==='+str)
         let list = that.data.messageList
         let obj = {
           text: str,
           from: 1
         }
         list.push(obj)
         that.setData({
           messageList: list
         })
       })
     },
     /**
      * 输入ip/端口号
      */
     addIp: function(event){
       this.mydata.remoteUrl.ip = event.detail.value
     },
     addPort: function (event){
       this.mydata.remoteUrl.port = event.detail.value
     },
     /**
      * 生命周期函数--监听页面初次渲染完成
      */
     onReady: function () {
     },
     /**
      * 生命周期函数--监听页面显示
      */
     onShow: function () {
     }
    }
    
    // util.newAb2Str代码
    function newAb2Str(arrayBuffer){
     let unit8Arr = new Uint8Array(arrayBuffer);
     let encodedString = String.fromCharCode.apply(null, unit8Arr),
       decodedString = decodeURIComponent(escape((encodedString)));//没有这一步中文会乱码
     return decodedString;
    }
    
    相应的WXML和WXSS代码
    
    <!-- wxml -->
    <!--pages/welcome/welcome.wxml-->
    <view>
      <view class='header'>
        <view>
          <text>本机端口:{{locationUrl.port}}</text>
        </view>
        <view class='headerItem'>
            <text>IP地址:</text>
            <input type='text' bindinput='addIp'></input>
          </view>
        <view class='headerItem'>
          <text>端口:</text>
          <input type='number' bindinput='addPort'></input>
        </view>
      </view>
      <view class='content'>
          <block wx:for="{{messageList}}" wx:key="{{index}}">
            <view wx:if="{{item.from === 1}}" class='fromLeft'>
              <text>{{item.text}}</text>
            </view>
            <view wx:else class='fromRight'>
              <text>{{item.text}}</text>
            </view>
          </block>
      </view>
      <view class='footer'>
        <input type='text' bindinput='addMessage'></input>
        <button bindtap='sendMessage'>发送</button>
      </view>
    </view>
    
    
    // wxss
    /* pages/welcome/welcome.wxss */
    .header{
      padding: 20rpx;
      border-bottom: solid 1px #dfdfdf;
    }
    .headerItem{
      display: flex;
      flex-direction: row;
      justify-content: flex-start;
      align-items: center;
      margin-top: 10rpx;
      height: 50rpx;
    }
    
    .headerItem > text{
      color: #333;
       150rpx;
      font-size: 30rpx;
      text-align: right;
    }
    
    .headerItem  > input{
      border: solid 1px #dfdfdf;
    }
    .content{
      padding: 0 20rpx;
    }
    
    .content > view{
      margin-top: 10rpx;
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
      align-items: flex-start;
    }
    
    .content > .fromLeft > text{
      padding: 10rpx;
       690rpx;
      text-align: left;
      background-color: orangered;
      color: white;
    }
    
    .content > .fromRight > text{
      padding: 10rpx;
       690rpx;
      text-align: right;
      background-color: #dfdfdf;
      color: white;
    }
    
    .footer{
      display: flex;
      flex-direction: row;
      justify-content: flex-start;
      align-items: center;
      padding: 0 20rpx;
      margin-top: 20rpx;
    }
    
    .footer > input{
      border: solid 2rpx #dfdfdf;
      border-radius: 4rpx;
       500rpx;
      height: 70rpx;
      line-height: 70rpx;
      margin-right: 10rpx;
    }
    
    .footer > button{
       200rpx;
      height: 70rpx;
      line-height: 70rpx;
    }
  • 相关阅读:
    信号灯的典型应用
    字符串过滤
    做一些学习的事情一定要坚持下去
    昨天的你造就今天的你,今天的你准备怎么造就明天的你呢?
    vue中计算属性,方法,侦听器
    vue模板语法
    Vue实例的生命周期钩子
    VUE实例
    简单的组件间传值
    前端组件化
  • 原文地址:https://www.cnblogs.com/qinlongqiang/p/12296753.html
Copyright © 2011-2022 走看看