Capacitor打包APP的UDP网络通信

由 夕空 撰写于  2021年1月22日

1.datagram的UDP插件

npm i cordova-plugin-datagram4

https://www.npmjs.com/package/cordova-plugin-datagram4

var datagram = cordova.require("cordova-plugin-datagram4.datagram");
var socket = datagram.createSocket("udp4");
var myPort = 3000;
var targetPort = 3001;
var targetIp = "target device ip";

socket.bind(listenPort, function(data) {
alert("bind \n" + JSON.parse(data));
});

socket.on("message", function(data, info) {
console.log(data + " / " + JSON.stringify(info));
});

var button = document.getElementById("button");
button.addEventListener(button, "click", function() {
var message = "HelloWorld";
if (message.length > 20480) {
alert("Too large!");
return;
}
socket.send(message, targetIp, targetPort, function() {
alert("done");
});
});

很遗憾,这个插件不支持16进制收发

2.谷歌API

因UDP通信已被谷歌废弃,需要NPM:

npm i cordova-plugin-chrome-apps-sockets-udp

buffer收发不好用,此段代码废弃!看下面
function convertStringToArrayBuffer(str) {//将字符串转化成buffer用于串口数据发送
var buf = new ArrayBuffer(str.length);// (str.length+1)增加一位来放回车符
var bufView = new Uint8Array(buf);
for (var i = 0; i < str.length; i++) {
bufView[i] = str.charCodeAt(i);
}
// bufView[str.length] = 13;//最后一位为回车符的ascii码
return buf;
};
function convertArrayBufferToString(buf) {//将串口接收到的buffer数据转化成字符串
var bufView = new Uint8Array(buf);
var encodedString = String.fromCharCode.apply(null, bufView);
// document.write(iconv.decode(encodedString, 'gbk'));
// return iconv.decode(encodedString, 'gbk');
return encodedString;
}


// 被谷歌浏览器废弃的UDP-API

var socketId;
// Handle the "onReceive" event.
var onReceive = function (info) {
// if (info.socketId !== socketId)
// return;
$('body').append('11411.data: ' + convertArrayBufferToString(info.data) + '<br>')
};

// Create the Socket
chrome.sockets.udp.create({ name: "why" }, function (socketInfo) {
socketId = socketInfo.socketId;
// Setup event handler and bind socket.
chrome.sockets.udp.onReceive.addListener(onReceive);
chrome.sockets.udp.bind(socketId, "0.0.0.0", 11411, function (result) {
if (result < 0) {
console.log("Error binding socket..................");
return;
}
chrome.sockets.udp.send(socketId, convertStringToArrayBuffer('send data'),
'192.168.1.108', 1337, function (sendInfo) {
console.log("sent " + sendInfo.bytesSent);
});

});
});


注意:模拟器里占用的端口号是随机的,只有部署安装版才正常(踩过的坑!)

convertStringToArrayBuffer(str)
convertArrayBufferToString(buf)

发现这个曾经在node.js使用的16进制Buffer互转方法在capacitor里不好用!!!

在网上找了好久才找到新方法:

function buf2hex(buffer, space) { // buffer is an ArrayBuffer
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join(space);
}

function hex2buf(key, space) {
key = '0x' + key.replace(new RegExp(space, 'g'), ',0x');
return new Uint8Array(key.split(",")).buffer;
}

var socketId;
var onReceive = function (info) {
$('body').prepend('IP:' + info.remoteAddress + ' Port:' + info.remotePort + '<br>' + buf2hex(info.data, ' ') + '<br>')
};

// Create the Socket
chrome.sockets.udp.create({ }, function (socketInfo) {
socketId = socketInfo.socketId;
// Setup event handler and bind socket.
chrome.sockets.udp.onReceive.addListener(onReceive);
chrome.sockets.udp.bind(socketId, "0.0.0.0", 11411, function (result) {
if (result < 0) {
console.log("Error binding socket..................");
return;
}
chrome.sockets.udp.send(socketId, hex2buf('FE 0F 00 00 00 08 01 FF F1 D1', ' '),
'192.168.1.108', 60000, function (sendInfo) {
console.log("sent " + sendInfo.bytesSent);
});

});
});

这里的需求时将 FE 0F 00 00 00 08 01 FF F1 D1 字符串发送和收到此类型的16进制,发送时需要分割加0x转Buffer发送。

hex2buf(key, space)

也就是转为 new Uint8Array([ 0xFE, 0x0F, 0x00, 0x00, 0x00, 0x08, 0x01, 0xFF, 0xF1, 0xD1 ]).buffer

buf2hex(buffer, space)

接收时又需要分割成字符串。

声明:星耀夕空|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - Capacitor打包APP的UDP网络通信


欢迎光顾我的小站!