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

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

浏览量:669 时间: 来源:yygood1

最近无意间看到微信小程序里多了个关于UDP的API,一时间感慨良多。想当初,小程序刚发布,想开发个局域网通信的程序,翻遍API居然没有,http/websocket要求域名,蓝牙只支持ble,郁闷得还专门找客服反馈。。。网上找了下,也没看到什么文章,那我就写个总结,顺便纪念下。

既然是通信,那么至少得有两个参与者,一端已经确定微信小程序了,另一端来点不一样的,Android吧(其实是作者Android出身~~)。

局域网通信,首先得有对方的地址,也就是ip和port,所以第一步就是设备搜索。所幸,小程序里有个mDNS的API,Android里也有个NSDManager(也就是mDNS的实现)。不清楚mDNS的,自行百度,笔者懒。。。

这样方案就确定了,通过mDNS发现设备,UDP通信。这里我们以Android端为Server,小程序为client,作为例子讲解。

mDNS发现设备

Android Server端

只需要调用NSDManager.registerService就实现了mDNS的注册:

private void mDNSRegister(){        mRegistrationListener = new NsdManager.RegistrationListener() {            @Override            public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {                Log.i(TAG,"onRegistrationFailed ");            }            @Override            public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {                Log.i(TAG,"onUnregistrationFailed ");            }            @Override            public void onServiceRegistered(NsdServiceInfo serviceInfo) {                Log.i(TAG,"onServiceRegistered ");            }            @Override            public void onServiceUnregistered(NsdServiceInfo serviceInfo) {                Log.i(TAG,"onServiceUnregistered ");            }        };        mNsdManager = (NsdManager) getSystemService(NSD_SERVICE);        NsdServiceInfo serviceInfo = new NsdServiceInfo();        serviceInfo.setServiceName("test");        serviceInfo.setPort(CHAT_PORT);//udp通信使用的端口号,通过mDNS发出去        serviceInfo.setServiceType("_test._udp.");//客户端发现服务器是需要对应的这个Type字符串        mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);    }

当然要记得在使用完后注销掉:

private void mDNSUnregister() {        mNsdManager.unregisterService(mRegistrationListener);    }

小程序 client端

开启设备搜索

startDiscovery: function () {    wx.startLocalServiceDiscovery({      serviceType: '_test._udp.',//对应上面server端注册的type      success: function (res) {        console.log(res)      },      fail: function (err) {        console.log(err)      },      complete: function () {        console.log('complete')      }    })  }

搜索到设备

onLocalService: function () {    let that = this    // 监听服务发现事件    wx.onLocalServiceFound(function (obj) {      console.log(obj)      serviceList.push(obj);      that.setData({        lists: serviceList      })    })

停止搜索

stopDiscovery: function () {    let that = this    wx.stopLocalServiceDiscovery({      success: function () {        that.showTips('停止搜索成功', 'success')        serviceList = []        resolveFailList = []        that.setData({          lists: [],          resolveFailList: []        })      },      fail: function () {        that.showTips('停止搜索失败,请重试!')      },      complete: function () {        console.log('stopDiscovery complete')      }    })  }

这样设备发现这一步就基本完成了。接下来就是udp通信了。

udp通信

Android Server端

private void startUdpListener(){        if(running){            return;        }        try {            socket = new DatagramSocket(CHAT_PORT);//绑定端口,暂未考虑端口占用,实际使用中可以使用循环增加端口号到方法来避免端口占用            packet = new DatagramPacket(buffer,BUFFER_SIZE);        } catch (SocketException e) {            e.printStackTrace();            return;        }        udpListenerThread = new Thread(new Runnable() {            @Override            public void run() {                while (running){                    try {                        socket.receive(packet);                    } catch (IOException e) {                        e.printStackTrace();                    }                    if (packet == null || packet.getLength() == 0) {                        Log.e(TAG, "无法接收UDP数据或者接收到的UDP数据为空");                        continue;                    }                    String strReceive = new String(packet.getData(), 0, packet.getLength());                    String ip = packet.getAddress().getHostAddress();                    int port = packet.getPort();                    Log.d(TAG, strReceive + " from " + ip + ":" + port);                    sendUdpMsg(ip,port,"received you message:"+strReceive);                }            }        });        running = true;        udpListenerThread.start();    }    //发送udp消息private void sendUdpMsg(String ip,int port,String message){        InetAddress targetAddress = null;        try {            targetAddress = InetAddress.getByName(ip);            DatagramPacket packet = new DatagramPacket(message.getBytes(), message.length(), targetAddress, port);            socket.send(packet);        } catch (Exception e) {            e.printStackTrace();        }    }

上面代码主要内容是开启一个线程,循环监听消息,收到消息后发送一个回复消息。

小程序 client端

var ip = this.data.lists[index].ip;    var port = this.data.lists[index].port;    const udp = wx.createUDPSocket();    udp.bind();    udp.send({      address: ip,      port: port,      message: "hello world!"    });    udp.onMessage(function (res){     //字符串转换,很重要      let unit8Arr = new Uint8Array(res.message);      let encodedString = String.fromCharCode.apply(null, unit8Arr);      let message = decodeURIComponent(escape((encodedString)));      that.setData({        receiveMessage: message,        fromIp: res.remoteInfo.address      })    });

上面代码主要内容是发送一个消息,并监听收到的消息
以上就是微信小程序和Android App局域网通信的重要部分了,完整代码已经整理好放在码云上了,有需要的可以自行下载。
https://gitee.com/yygood1/wechat_demo_udp

版权声明

即速应用倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至197452366@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于即速应用观点。用户与作者的任何交易与本站无关,请知悉。

产品经理

手机 : 13312967497

擅长 : 小程序流量变现

扫码领取礼包

热门模板

  • 头条
  • 搜狐
  • 微博
  • 百家
  • 一点资讯
  • 知乎