Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wx-school-app-public
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
姜雷
wx-school-app-public
Commits
7d9d885d
Commit
7d9d885d
authored
Jul 08, 2019
by
姜雷
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加蓝牙和websocket的hook方法
parent
e77fcdb1
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
561 additions
and
0 deletions
+561
-0
useBluetooth.ts
src/hooks/useBluetooth.ts
+403
-0
useDeviceWS.ts
src/hooks/useDeviceWS.ts
+158
-0
No files found.
src/hooks/useBluetooth.ts
0 → 100644
View file @
7d9d885d
import
Taro
,
{
useEffect
,
useReducer
}
from
'@tarojs/taro'
;
import
{
ab2str
,
str2ab
}
from
'@/utils/arrayBuffer'
;
import
Actions
from
'@/types/Store/Actions'
;
enum
BlueToothError
{
BlueToothNotOpen
=
'BlueToothNotOpen'
,
DeviceNotFound
=
'DeviceNotFound'
,
}
type
NotifyUUIDs
=
{
notifyId
:
string
;
writeId
:
string
;
readId
:
string
;
};
type
DeviceInfo
=
{
deviceId
:
string
;
uuid
:
string
;
isPrimary
:
boolean
;
serviceId
:
string
;
notifyId
:
string
;
writeId
:
string
;
readId
:
string
;
};
type
StoreState
=
{
bluetoothState
:
boolean
;
deviceDone
:
boolean
;
deviceInfo
:
DeviceInfo
;
};
const
initState
=
{
bluetoothState
:
false
,
deviceDone
:
false
,
deviceInfo
:
{
deviceId
:
''
,
uuid
:
''
,
isPrimary
:
false
,
serviceId
:
''
,
notifyId
:
''
,
writeId
:
''
,
readId
:
''
,
},
};
const
reducer
=
(
state
:
StoreState
,
action
:
Actions
):
StoreState
=>
{
switch
(
action
.
type
)
{
case
'BLUETOOTH_STATE_CHANGE'
:
return
{
...
state
,
bluetoothState
:
action
.
payload
,
};
case
'GET_DEVICE_ID'
:
return
{
...
state
,
deviceInfo
:
{
...
state
.
deviceInfo
,
deviceId
:
action
.
payload
,
},
};
case
'GET_NOTIFY_UUID'
:
return
{
...
state
,
deviceInfo
:
{
...
state
.
deviceInfo
,
...
action
.
payload
,
},
};
case
'DEVICE_STATE_CHANGE'
:
return
{
...
state
,
deviceDone
:
action
.
payload
,
};
default
:
return
state
;
}
};
const
useBluetooth
=
(
deviceCode
:
string
,
getBluetoothData
:
(
data
:
string
)
=>
void
,
):
{
state
:
boolean
;
sendMessageToDevice
:
(
msg
:
string
,
)
=>
Promise
<
Taro
.
writeBLECharacteristicValue
.
Promised
>
;
}
=>
{
const
[
state
,
dispatch
]
=
useReducer
(
reducer
,
initState
);
const
warnBluetoothOpen
=
()
=>
{
return
Taro
.
showModal
({
title
:
'警告'
,
content
:
'为保障正常使用,请打开蓝牙功能'
,
});
};
const
DevicesDiscoveryHandle
=
():
Promise
<
string
>
=>
{
let
timer
:
NodeJS
.
Timeout
|
null
=
null
;
return
new
Promise
((
resolve
,
reject
)
=>
{
// if (isOnlyBluetooth) {
// timer = setTimeout(() => {
// reject({ msg: BlueToothError.DeviceNotFound });
// }, 10000);
// } else {
timer
=
setTimeout
(()
=>
{
reject
({
msg
:
BlueToothError
.
DeviceNotFound
});
},
5000
);
// }
Taro
.
onBluetoothDeviceFound
(
res
=>
{
const
devices
=
res
.
devices
;
if
(
devices
[
0
].
name
===
deviceCode
)
{
let
deviceId
=
devices
[
0
].
deviceId
;
Taro
.
stopBluetoothDevicesDiscovery
();
dispatch
({
type
:
'GET_DEVICE_ID'
,
payload
:
deviceId
});
if
(
timer
)
{
clearInterval
(
timer
);
}
resolve
(
deviceId
);
}
});
});
};
const
createConnection
=
(
deviceId
:
string
):
Promise
<
string
>
=>
{
return
new
Promise
((
resolve
,
reject
)
=>
{
Taro
.
createBLEConnection
({
deviceId
,
});
let
abStr
=
''
;
Taro
.
onBLECharacteristicValueChange
(
res
=>
{
console
.
log
(
`characteristic
${
res
.
characteristicId
}
has changed, now is
${
res
.
value
}
`
,
);
console
.
log
(
res
.
value
);
let
datastr
=
ab2str
(
res
.
value
);
console
.
log
(
'获取socket消息: '
,
datastr
);
if
(
datastr
===
'<>'
)
{
console
.
log
(
'结束蓝牙以及socket: '
,
datastr
);
this
.
closeDeviceSocket
();
this
.
closeBluetoothConnection
();
}
else
{
if
(
datastr
.
substring
(
0
,
1
)
===
'{'
&&
datastr
.
substring
(
datastr
.
length
-
1
,
datastr
.
length
)
===
'}'
)
{
console
.
log
(
'<---发送完整数据: '
,
datastr
);
// if (socketTask) {
// socketTask.send({
// data: str2ab(datastr),
// success: msg => {
// console.log('发送完整数据:', msg, '--->');
// },
// fail: err => {
// console.log('发送完整数据:', err, '--->');
// },
// });
// }
getBluetoothData
(
datastr
);
}
else
if
(
datastr
.
substring
(
0
,
1
)
===
'{'
)
{
console
.
log
(
'接受头部数据: '
,
datastr
);
abStr
=
datastr
;
}
else
if
(
abStr
.
length
&&
datastr
.
substring
(
datastr
.
length
-
1
,
datastr
.
length
)
===
'}'
)
{
abStr
+=
datastr
;
console
.
log
(
'接受尾部数据后: '
,
abStr
);
console
.
log
(
'<---发送完整数据: '
,
abStr
);
// if (socketTask) {
// socketTask.send({
// data: str2ab(abStr),
// success: msg => {
// console.log('发送完整数据:', msg, '--->');
// },
// fail: err => {
// console.log('发送完整数据:', err, '--->');
// },
// });
// }
getBluetoothData
(
datastr
);
abStr
=
''
;
}
else
{
console
.
log
(
'弃掉数据:'
,
datastr
);
}
}
});
Taro
.
onBLEConnectionStateChange
(
res
=>
{
// const { showerState } = this.state;
console
.
log
(
`device
${
res
.
deviceId
}
state has changed, connected:
${
res
.
connected
}
`
,
);
if
(
res
.
connected
)
{
// this.setState({
// deviceDone: true,
// showerState: true,
// });
dispatch
({
type
:
'DEVICE_STATE_CHANGE'
,
payload
:
true
});
resolve
(
res
.
deviceId
);
}
else
{
console
.
log
(
res
);
this
.
setState
({
deviceDone
:
false
,
});
dispatch
({
type
:
'DEVICE_STATE_CHANGE'
,
payload
:
false
});
// if (showerState) {
// this.reConnectDeviceBluetooth();
// }
reject
(
'蓝牙未成功连接'
);
}
});
});
};
const
getDeviceServices
=
(
deviceId
:
string
,
):
Promise
<
{
deviceId
:
string
;
serviceId
:
string
;
}
>
=>
{
return
Taro
.
getBLEDeviceServices
({
deviceId
:
deviceId
,
}).
then
(
services
=>
{
const
serviceArr
=
services
.
services
;
let
tempService
=
serviceArr
.
find
(
item
=>
item
.
uuid
.
toLocaleLowerCase
()
===
'6e401103-b5a3-f393-e0a9-e50e24dcca9e'
,
);
let
service
:
Taro
.
getBLEDeviceServices
.
PromisedPropServicesItem
=
tempService
?
tempService
:
services
[
0
];
console
.
log
(
'获取全部services: '
,
services
,
'. serviceId: '
,
service
);
const
serviceId
=
service
.
uuid
;
return
{
deviceId
:
deviceId
,
serviceId
:
serviceId
};
});
};
const
getDeviceCharacter
=
({
deviceId
,
serviceId
,
}:
{
deviceId
:
string
;
serviceId
:
string
;
}):
Promise
<
NotifyUUIDs
>
=>
{
return
Taro
.
getBLEDeviceCharacteristics
({
deviceId
,
serviceId
,
}).
then
(
res
=>
{
let
notifyId
=
''
,
writeId
=
''
,
readId
=
''
;
for
(
let
i
=
0
;
i
<
res
.
characteristics
.
length
;
i
++
)
{
let
charc
=
res
.
characteristics
[
i
];
if
(
charc
.
properties
.
notify
)
{
notifyId
=
charc
.
uuid
;
}
if
(
charc
.
properties
.
write
)
{
writeId
=
charc
.
uuid
;
}
if
(
charc
.
properties
.
write
)
{
readId
=
charc
.
uuid
;
}
}
dispatch
({
type
:
'GET_NOTIFY_UUID'
,
payload
:
{
notifyId
,
writeId
,
readId
,
},
});
return
{
notifyId
,
writeId
,
readId
,
};
});
};
const
openNotify
=
({
notifyId
}:
NotifyUUIDs
)
=>
{
const
{
deviceInfo
}
=
this
.
state
;
return
Taro
.
notifyBLECharacteristicValueChange
({
deviceId
:
deviceInfo
.
deviceId
,
serviceId
:
deviceInfo
.
serviceId
,
characteristicId
:
notifyId
,
state
:
true
,
}).
then
(
res
=>
{
console
.
log
(
res
);
let
abStr
=
''
;
Taro
.
onBLECharacteristicValueChange
(
res
=>
{
let
msg
=
ab2str
(
res
.
value
);
console
.
log
(
'获取蓝牙设备消息: '
,
msg
);
if
(
msg
===
'<>'
)
{
this
.
closeBluetoothConnection
();
this
.
closeDeviceSocket
();
}
else
{
if
(
msg
.
substring
(
0
,
1
)
===
'{'
&&
msg
.
substring
(
msg
.
length
-
1
,
msg
.
length
)
===
'}'
)
{
getBluetoothData
(
msg
);
}
else
if
(
msg
.
substring
(
0
,
1
)
===
'{'
)
{
abStr
=
msg
;
}
else
if
(
abStr
.
length
&&
msg
.
substring
(
msg
.
length
-
1
,
msg
.
length
)
===
'}'
)
{
abStr
+=
msg
;
getBluetoothData
(
abStr
);
abStr
=
''
;
}
else
{
if
(
abStr
.
length
)
{
abStr
+=
msg
;
}
else
{
console
.
log
(
'弃掉数据:'
,
msg
);
}
}
}
});
});
};
const
sendMessageToDevice
=
(
msg
:
string
)
=>
{
const
{
deviceInfo
}
=
state
;
console
.
log
(
msg
,
str2ab
(
msg
).
byteLength
);
if
(
deviceInfo
.
writeId
)
{
return
Taro
.
writeBLECharacteristicValue
({
deviceId
:
deviceInfo
.
deviceId
,
serviceId
:
deviceInfo
.
serviceId
,
characteristicId
:
deviceInfo
.
writeId
,
value
:
str2ab
(
msg
),
});
}
else
{
return
Promise
.
reject
();
}
};
useEffect
(()
=>
{
Taro
.
onBluetoothAdapterStateChange
(
res
=>
{
console
.
log
(
'adapterState changed, now is'
,
res
);
if
(
res
.
available
)
{
dispatch
({
type
:
'BLUETOOTH_STATE_CHANGE'
,
payload
:
true
});
}
else
{
dispatch
({
type
:
'BLUETOOTH_STATE_CHANGE'
,
payload
:
false
});
}
});
Taro
.
openBluetoothAdapter
()
.
then
(
res
=>
{
console
.
log
(
'openBluetoothAdapter: '
,
res
);
dispatch
({
type
:
'BLUETOOTH_STATE_CHANGE'
,
payload
:
true
});
})
.
catch
(
err
=>
{
console
.
error
(
err
);
});
return
()
=>
{
Taro
.
closeBluetoothAdapter
();
};
},
[]);
useEffect
(()
=>
{
if
(
state
)
{
Taro
.
startBluetoothDevicesDiscovery
()
.
then
(
DevicesDiscoveryHandle
)
.
then
(
createConnection
)
.
then
(
getDeviceServices
)
.
then
(
getDeviceCharacter
)
.
then
(
openNotify
)
.
then
(()
=>
{
dispatch
({
type
:
'DEVICE_STATE_CHANGE'
,
payload
:
true
});
})
.
catch
(
err
=>
{
// Taro.stopBluetoothDevicesDiscovery();
// if (timer) {
// clearInterval(timer);
// }
// Taro.hideLoading();
console
.
error
(
'startBluetoothDevicesDiscovery: '
,
err
);
// if (err.msg === BlueToothError.DeviceNotFound) {
Taro
.
stopBluetoothDevicesDiscovery
();
// this.sendStartShower();
throw
err
;
// } else {
// return this.warnBluetoothOpen();
// }
});
}
else
{
warnBluetoothOpen
();
}
},
[
state
,
deviceCode
]);
return
{
state
:
state
.
bluetoothState
,
sendMessageToDevice
,
};
};
export
default
useBluetooth
;
src/hooks/useDeviceWS.ts
0 → 100644
View file @
7d9d885d
import
Actions
from
'@/types/Store/Actions'
;
import
Taro
,
{
useReducer
,
useEffect
}
from
'@tarojs/taro'
;
import
{
str2ab
,
ab2str
}
from
'@/utils/arrayBuffer'
;
type
StoreState
=
{
socketState
:
boolean
;
socketTask
:
Taro
.
SocketTask
|
null
;
};
const
StopCode
=
1000
;
let
reConnectting
:
boolean
=
false
;
let
timer
:
NodeJS
.
Timeout
|
null
=
null
;
const
initState
=
{
socketState
:
false
,
socketTask
:
null
,
};
const
reducer
=
(
state
:
StoreState
,
action
:
Actions
):
StoreState
=>
{
switch
(
action
.
type
)
{
case
'GET_SOCKET_TASK'
:
return
{
...
state
,
socketTask
:
action
.
payload
};
case
'SOCKET_STATE_CHANGE'
:
return
{
...
state
,
socketState
:
action
.
payload
};
default
:
return
state
;
}
};
const
useDeviceWS
=
({
url
,
getSocketData
,
}:
{
url
:
string
;
getSocketData
:
(
msg
:
string
)
=>
void
;
}):
{
state
:
StoreState
;
sendMessageToServer
:
(
msg
:
string
,
successHandle
:
Taro
.
SocketTask
.
send
.
ParamPropSuccess
,
failHandle
:
Taro
.
SocketTask
.
send
.
ParamPropFail
,
)
=>
void
;
}
=>
{
const
[
state
,
dispatch
]
=
useReducer
(
reducer
,
initState
);
const
connectDeviceSocket
=
(
url
:
string
)
=>
{
Taro
.
connectSocket
({
url
:
url
}).
then
(
task
=>
{
dispatch
({
type
:
'GET_SOCKET_TASK'
,
payload
:
task
});
task
.
onOpen
(()
=>
{
console
.
log
(
'onOpen'
);
if
(
reConnectting
)
{
// reConnectDeviceSocket(true);
timer
&&
clearTimeout
(
timer
);
timer
=
null
;
reConnectting
=
false
;
}
task
.
send
({
data
:
str2ab
(
'{}'
)
});
dispatch
({
type
:
'SOCKET_STATE_CHANGE'
,
payload
:
true
});
// this.sendDeviceCode();
});
task
.
onMessage
(
res
=>
{
const
msg
:
string
=
ab2str
(
res
.
data
);
console
.
log
(
'socket onMessage: '
,
msg
);
if
(
msg
===
'[0]'
)
{
console
.
log
(
'结束蓝牙以及socket: '
,
msg
);
closeDeviceSocket
();
}
else
if
(
msg
===
'[]'
)
{
}
else
{
if
(
msg
.
length
>
100
)
{
getSocketData
(
'[]'
);
}
else
if
(
msg
.
length
>
20
)
{
for
(
let
index
=
0
;
index
<=
Math
.
floor
(
msg
.
length
/
20
);
index
++
)
{
let
str
=
msg
.
substring
(
index
*
20
,
(
index
+
1
)
*
20
);
getSocketData
(
str
);
}
}
else
{
if
(
msg
)
{
getSocketData
(
msg
);
}
}
}
});
task
.
onClose
(
e
=>
{
console
.
log
(
'socked关闭'
,
e
,
reConnectting
,
timer
);
dispatch
({
type
:
'SOCKET_STATE_CHANGE'
,
payload
:
false
});
dispatch
({
type
:
'GET_SOCKET_TASK'
,
payload
:
null
});
if
(
e
.
code
===
StopCode
)
{
console
.
log
(
'正确结束socket连接'
);
}
else
{
console
.
log
(
'开始重连socket'
);
reConnectDeviceSocket
();
}
});
});
};
const
closeDeviceSocket
=
()
=>
{
const
{
socketTask
}
=
state
;
console
.
log
(
'in close'
,
socketTask
,
timer
);
if
(
socketTask
)
{
socketTask
.
close
({
code
:
StopCode
,
complete
:
()
=>
{
dispatch
({
type
:
'SOCKET_STATE_CHANGE'
,
payload
:
false
});
dispatch
({
type
:
'GET_SOCKET_TASK'
,
payload
:
null
});
},
});
}
if
(
timer
)
{
clearTimeout
(
timer
);
}
};
const
reConnectDeviceSocket
=
()
=>
{
console
.
log
(
reConnectting
,
timer
);
if
(
reConnectting
)
{
connectDeviceSocket
(
url
);
}
else
if
(
timer
)
{
clearTimeout
(
timer
);
reConnectting
=
false
;
timer
=
null
;
console
.
log
(
'请保证网络正常'
);
Taro
.
showModal
({
title
:
'警告'
,
content
:
'请保持网络畅通正常'
,
});
}
else
{
timer
=
setTimeout
(()
=>
{
reConnectting
=
false
;
},
10000
);
reConnectting
=
true
;
console
.
log
(
reConnectting
,
timer
);
connectDeviceSocket
(
url
);
}
};
const
sendMessageToServer
=
(
msg
:
string
,
successHandle
:
Taro
.
SocketTask
.
send
.
ParamPropSuccess
,
failHandle
:
Taro
.
SocketTask
.
send
.
ParamPropFail
,
)
=>
{
const
{
socketTask
}
=
state
;
socketTask
&&
socketTask
.
send
({
data
:
str2ab
(
msg
),
success
:
successHandle
,
fail
:
failHandle
,
});
};
useEffect
(()
=>
{
connectDeviceSocket
(
url
);
return
closeDeviceSocket
;
},
[
url
]);
return
{
state
,
sendMessageToServer
};
};
export
default
useDeviceWS
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment