基于wifiManager实现P2P连接
WiFi P2P简介 基本原理 WiFi Direct协议是Wi-Fi联盟发展、支持与授予认证的一套软件协议,也被称为Wi-Fi点对点(Wi-Fi Peer-to-Peer,简称P2P)。这套协议允许无线网络中的设备无需通过无线路由器即可相互连接,以点对点的方式直接与另一个 WiFi 设备连线,进行数据高速传输。
WiFi P2P简介
基本原理
WiFi Direct协议是Wi-Fi联盟发展、支持与授予认证的一套软件协议,也被称为Wi-Fi点对点(Wi-Fi Peer-to-Peer,简称P2P)。这套协议允许无线网络中的设备无需通过无线路由器即可相互连接,以点对点的方式直接与另一个 WiFi 设备连线,进行数据高速传输。
通常A与B通信是通过服务器转发数据。
P2P则可以实现A与B直接通信。
技术特点
- 连接方式:允许 WiFi 设备直接连接,无需通过 AP,从而简化连接流程,提高了数据传输的便捷性。
- 传输性能:在传输速度与传输距离方面比蓝牙有大幅度提升,最大传输距离可达 200 米,最大传输速度为 250Mbps。
- 加密机制:支持 WPA2 加密机制,确保数据传输的安全性。
应用场景
- 文件传输:可以在手机和平板之间快速传输照片、视频等大文件。
- 内容共享:在会议中直接通过电脑展示手机内容,或在不同设备间共享应用。
- 文档打印:直接连接打印机进行打印。
- 数据同步:在设备间同步数据。
- 娱乐应用:支持近距离的设备互联,适用于游戏、聊天、车机交互。
方案描述
通过wifiManager实现P2P连接,前提需要打开设备WLAN开关,整体方案分为建立P2P连接和P2P连接场景验证两个部分:
- 建立P2P连接: 发现设备并与P2P设备建立连接。
- P2P连接场景验证:验证P2P连接后的socket通信,模拟用户与车机交互。
建立P2P连接
1. 发现设备:P2P连接需要先发现P2P设备才能进行连接。
a. 注册发现设备状态监听。注册发现设备状态改变事件,注册事件可通过回调监听设备发现服务是否开启成功。
aboutToAppear(): void {
// 注册发现设备状态监听
wifiManager.on("p2pDiscoveryChange", this.recvP2pDiscoveryChangeFunc);
}
在业务退出时,要调用wifiManager.off('p2pDiscoveryChange')接口注销注册回调。
aboutToDisappear():
// 注销发现设备状态监听
wifiManager.off("p2pDiscoveryChange", this.recvP2pDiscoveryChangeFunc);
}
发现设备回调事件: 0- 初始状态。 1-发现成功。
// 发现设备状态改变事件。
recvP2pDiscoveryChangeFunc = (result: number) => {
promptAction.showToast({
message: result == 1 ? '发现设备成功' : '发现设备失败',
duration: 2000
});
}
开始发现设备,wifiManager.startDiscoverDevices接口为开启P2P发现设备关键步骤,发现设备状态结果通过监听事件回调。
Button('开始发现设备').onClick(() => {
try {
wifiManager.startDiscoverDevices();
} catch (error) {
console.error("wifiManager.startDiscoverDevices failed:" + JSON.stringify(error));
}
})
b. 获取设备列表。
当发现设备阶段完成,即发现设备状态监听事件回调为1,此时设备可被p2p设备发现,且通过wifiManager.getP2pPeerDevices可获取对端设备列表。
// 获取P2P对端设备列表信息
getPeerDeviceList() {
// p2p发现阶段完成,才能正常获取到对端设备列表信息
this.peerDevices = []
wifiManager.getP2pPeerDevices((err, data) => {
if (err) {
console.error("get P2P peer devices error");
return;
}
console.info("get P2P peer devices: " + JSON.stringify(data));
this.peerDevices = data
});
}
2. 建立连接。
a. 通过已发现设备WifiP2pDevice进行连接。
建立p2p连接会有连接状态回调,通知连接状态变化,可根据状态变化实现对应逻辑。首先声明监听事件recvP2pConnectionChangeFunc。
// p2p连接状态改变事件
recvP2pConnectionChangeFunc = (result: wifiManager.WifiP2pLinkedInfo) => {
console.info("p2p connection change receive event: " + JSON.stringify(result));
if (result.connectState == 1) {
promptAction.showToast({
message: '已连接',
duration: 2000
});
}
}
再通过wifiManager.on("p2pConnectionChange")注册p2p连接状态监听。
aboutToAppear(): void {
// 注册p2p连接状态监听
wifiManager.on("p2pConnectionChange", this.recvP2pConnectionChangeFunc)
}
p2p连接状态监听在业务结束时通过wifiManager.off("p2pConnectionChange")注销。
aboutToDisappear(): void {
// 注销p2p连接状态监听
wifiManager.off('p2pConnectionChange',this.recvP2pConnectionChangeFunc)
}
从扫描到的设备列表中,选择需要连接的设备通过wifiManager.p2pConnect进行P2P连接。
// 建立对端连接
connectToPeerDevice(device: wifiManager.WifiP2pDevice) {
let config: wifiManager.WifiP2PConfig = {
deviceAddress: device.deviceAddress,
deviceAddressType: device.deviceAddressType,
netId: 0,
passphrase: "",
groupName: "",
goBand: 0,
}
try {
wifiManager.p2pConnect(config);
} catch (e) {
console.error("wifiManager.p2pConnect error ", e.code);
}
}
b. 获取P2P连接群组信息。
p2p连接成功后获取当前群组信息,获取goIpAddress,通过goIpAddress可与对端服务进行通信。
// 获取当前群组信息
getGroupInfo(){
wifiManager.getCurrentGroup((err, data) => {
if (err) {
console.error("get current P2P group error");
return;
}
console.info("get current P2P group: " + JSON.stringify(data));
this.goIpAddress = data.goIpAddress
});
}
P2P连接场景验证:
1,手机模拟车机系统。
效果图:用户连接车机socket成功
const tcpServer = socket.constructTCPSocketServerInstance()
export function createServer(callback: Callback<boolean>): void {
let ipAddress : socket.NetAddress = {} as socket.NetAddress
ipAddress.address = "0.0.0.0"
ipAddress.port = 4651
tcpServer.listen(ipAddress, (err: BusinessError) => {
if (err) {
console.log("listen fail");
return
}
console.log("listen success");
promptAction.showToast({
message: JSON.stringify('listen success'),
duration: 2000
})
})
class SocketInfo {
message: ArrayBuffer = new ArrayBuffer(1);
remoteInfo: socket.SocketRemoteInfo = {} as socket.SocketRemoteInfo;
}
// Listen client connect to server
tcpServer.on("connect", (connection: socket.TCPSocketConnection) => {
tcpConnectArray.pop()
tcpConnectArray.push(connection)
// Listen connection closed
connection.on("close", () => {
console.info("on close success")
});
// Listen receive message
connection.on("message", (value: SocketInfo) => {
let buffer = value.message
let dataView = new DataView(buffer);
let str = ""
for (let i = 0; i < dataView.byteLength; ++i) {
str += String.fromCharCode(dataView.getUint8(i))
}
// Response to client
response()
// Toast message
promptAction.showToast({
message: JSON.stringify(str),
duration: 2000
})
})
// Send data to the client for Connection state.
let tcpSendOptions : socket.TCPSendOptions = {} as socket.TCPSendOptions
tcpSendOptions.data = 'Hello, client, connect success!'
connection.send(tcpSendOptions, (err: BusinessError) => {
if (err) {
console.log("send fail")
return
}
console.log("send success")
})
})
}
2,手机应用连接车机服务
效果图:连接车机socket成功
通过p2p连接获取到的goIpAddress连接车机Socket服务:
// 连接车机Socket服务
createSocketClient(){
let ipAddress: socket.NetAddress = {} as socket.NetAddress;
ipAddress.address = this.goIpAddress;
ipAddress.port = 4651;
let tcpConnect: socket.TCPConnectOptions = {} as socket.TCPConnectOptions;
tcpConnect.address = ipAddress;
tcpConnect.timeout = 6000;
tcp.connect(tcpConnect, (err: BusinessError) => {
if (err) {
console.log('connect fail' + JSON.stringify(err));
return;
}
console.log('connect success');
});
}
3,手机应用向车机服务发送消息
效果图:车机收到用户发送的‘hello,my car!’
// 发送消息
let clientSendOptions: socket.TCPSendOptions = {} as socket.TCPSendOptions;
export function sendMsg() {
clientSendOptions.data = 'hello,my car!';
tcp.send(clientSendOptions, (err: BusinessError) => {
if (err) {
console.log('sendMsg fail ');
return;
}
console.warn('fxm debug : client sendMsg success');
})
}
4,车机服务响应手机应用消息
效果图:用户收到车机响应的‘hello,have a good day!’
在创建的车机socket server中,有接受消息的监听,监听到手机应用请求后,做出响应。
export function response() {
let connection: socket.TCPSocketConnection = tcpConnectArray[0];
let tcpSendOptions: socket.TCPSendOptions = {} as socket.TCPSendOptions
tcpSendOptions.data = 'hello,have a good day!'
connection.send(tcpSendOptions, (err: BusinessError) => {
if (err) {
console.log("response fail")
return
}
console.log("response success")
})
}
5,车机服务向手机应用推送消息
效果图:用户收到车机推送的‘hello, the car has reached its destination!’
车机系统也可向手机应用主动推送消息。
let tcpSendOptions : socket.TCPSendOptions = {} as socket.TCPSendOptions
tcpSendOptions.data = 'hello, the car has reached its destination!'
connection.send(tcpSendOptions, (err: BusinessError) => {
if (err) {
console.log("send fail")
return
}
console.log("send success")
})
到此则实现p2p连接后的socket通信验证。
更多推荐
所有评论(0)