小程序UDP通信

前言

UDP通信分為單播 廣播 組播,基礎(chǔ)庫2.7.0之后,小程序開始支持UDP通信,目前小程序只支持單播。

小程序API

小程序UDP通信這一塊可以說是很簡單了就一個UDPSocket實(shí)例。然后bind()方法綁定端口,send()方法發(fā)送數(shù)據(jù),close()方法關(guān)閉通信,onMessage()方法監(jiān)聽消息等等,具體可以去看文檔

相關(guān)技術(shù)難點(diǎn)

使用UDP通信時,如果是用于局域網(wǎng)內(nèi)通信,這里有個難點(diǎn)就是,不知道本機(jī)及對應(yīng)要通信設(shè)備在當(dāng)前局域網(wǎng)內(nèi)的ip及綁定的端口。如果是用于和服務(wù)器之間的數(shù)據(jù)傳輸?shù)脑?,沒想出具體應(yīng)用場景...

咨詢了一下做嵌入式的朋友,他說硬件部分可以綁定一個固定的端口號。(這樣的話可以通過mDNS和固定端口號把需要通信對象的ip/port拼出來。)

通信效果展示

由于沒有2臺手機(jī),所以用node.js代碼充當(dāng)了其中一臺客戶端,先看看客戶端間通信截圖。


client1.png

client2.png

Node.js端代碼

通過dgram框架進(jìn)行操作,這里由于演示,所以每次都簡單地返回相同的數(shù)據(jù)。

const dgram = require('dgram');
const server = dgram.createSocket('udp4');
server.on('close',()=>{
    console.log('socket已關(guān)閉');
});
server.on('error',(err)=>{
    console.log(err);
});
server.on('listening',()=>{
    console.log('socket正在監(jiān)聽中...');
});
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消息時,數(shù)據(jù)是ArrayBuffter格式的,需要轉(zhuǎn)成string顯示。(這部分代碼在js代碼最下方)

// js代碼
// pages/welcome/welcome.js
let util = require('../../utils/util.js')
Page({
 udpSocket:null,
 /**
  * 頁面的初始數(shù)據(jù)
  */
 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: '請輸入內(nèi)容',
     })
     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
   })
 },
 /**
  * 生命周期函數(shù)--監(jiān)聽頁面加載
  */
 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('監(jiān)聽中...')
     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
 },
 /**
  * 生命周期函數(shù)--監(jiān)聽頁面初次渲染完成
  */
 onReady: function () {
 },
 /**
  * 生命周期函數(shù)--監(jiān)聽頁面顯示
  */
 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;
}

相應(yīng)的WXML和WXSS代碼

<!-- wxml -->
<!--pages/welcome/welcome.wxml-->
<view>
  <view class='header'>
    <view>
      <text>本機(jī)端口:{{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'>發(fā)送</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;
  width: 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;
  width: 690rpx;
  text-align: left;
  background-color: orangered;
  color: white;
}

.content > .fromRight > text{
  padding: 10rpx;
  width: 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;
  width: 500rpx;
  height: 70rpx;
  line-height: 70rpx;
  margin-right: 10rpx;
}

.footer > button{
  width: 200rpx;
  height: 70rpx;
  line-height: 70rpx;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、簡歷準(zhǔn)備 1、個人技能 (1)自定義控件、UI設(shè)計(jì)、常用動畫特效 自定義控件 ①為什么要自定義控件? Andr...
    lucas777閱讀 5,382評論 2 54
  • 個人認(rèn)為,Goodboy1881先生的TCP /IP 協(xié)議詳解學(xué)習(xí)博客系列博客是一部非常精彩的學(xué)習(xí)筆記,這雖然只是...
    貳零壹柒_fc10閱讀 5,192評論 0 8
  • 概要 64學(xué)時 3.5學(xué)分 章節(jié)安排 電子商務(wù)網(wǎng)站概況 HTML5+CSS3 JavaScript Node 電子...
    阿啊阿吖丁閱讀 9,813評論 0 3
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,639評論 1 32
  • 計(jì)算機(jī)網(wǎng)絡(luò)概述 網(wǎng)絡(luò)編程的實(shí)質(zhì)就是兩個(或多個)設(shè)備(例如計(jì)算機(jī))之間的數(shù)據(jù)傳輸。 按照計(jì)算機(jī)網(wǎng)絡(luò)的定義,通過一定...
    蛋炒飯_By閱讀 1,365評論 0 10

友情鏈接更多精彩內(nèi)容