技术经验 • dingxiao • 阅读数:2184 • 2019年2月20日 11:30
一直想做移动端的开发,在对RN有了初步的了解后,便开始了动手实践。
先拿自己比较熟悉的mqtt进行测试,关键自己也刚好有一套现成的mqtt运行平台。
Demo版的代码很简单,即完成与mqtt服务器的连接,订阅相关消息和发布相关控制消息。
这里mqtt服务器的连接选用了websocket的方式进行连接,端口也是mqtt服务器指定的服务端口。
创建websocket方式的mqtt连接代码为:
const client = new Client({ uri: "ws://ip地址:prot/", clientId: 'dx' + (new Date()).getTime(), storage: myStorage });
接收mqtt消息的代码:
//获取消息标题
var topic = entry.destinationName;
//获取消息内容
entry.payloadString;
//获取消息字节内容
data = entry.payloadBytes;
//将字节内容转换成base64格式
base64Icon = binaryToBase64(data);
//通过setState方式刷新图片显示
this.setState({message: [...this.state.pic_flag, pic_count]});
通过render函数进行前端渲染的代码:
<Image
style={{
width: 320,
height: 300,
resizeMode: 'contain',
}}
source={{uri: `data:image/gif;base64,${base64Icon}`}}
/>
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
//import init from 'react_native_mqtt';
import {
Platform,
StyleSheet,
Text,
View,
TouchableHighlight,
TextInput,
Button,
Image
} from 'react-native';
import { Client, Message } from 'react-native-paho-mqtt';
import { MaterialDialog } from 'react-native-material-dialog';
const instructions = Platform.select({
ios: 'Press Cmd+R to reload,\n' +
'Cmd+D or shake for dev menu',
android: 'Double tap R on your keyboard to reload,\n' +
'Shake or press menu button for dev menu',
});
var base64Icon;
var pic_count = 0;
var location_f = 5;
var location_x = 5;
var Str_Location;
export default class App extends Component<{}> {
constructor(){
super();
const myStorage = {
setItem: (key, item) => {
myStorage[key] = item;
},
getItem: (key) => myStorage[key],
removeItem: (key) => {
delete myStorage[key];
},
};
//创建mqtt连接
const client = new Client({ uri: "ws://ip地址:prot/", clientId: 'dx' + (new Date()).getTime(), storage: myStorage });
client.on('messageReceived', (entry) => {
//console.log(entry);
var topic = entry.destinationName;
var binaryToBase64 = require('binaryToBase64');
if(topic != "pic")
{
this.setState({message: [...this.state.message, entry.payloadString]});
}
else if(topic == "pic")
{
pic_count = pic_count + 1;
data = entry.payloadBytes;
base64Icon = binaryToBase64(data);
//this.setState({message: [...this.state.message, 'pic']});
this.setState({message: [...this.state.pic_flag, pic_count]});
}
});
client.on('connectionLost', (responseObject) => {
if (responseObject.errorCode !== 0) {
console.log(responseObject.errorMessage);
this.setState({error: 'Lost Connection', isConnected: false});
}
});
this.connect(client)
.then(() => {
console.log('connect!');
this.setState({isConnected: true, error: ''})
})
.catch((error)=> {
console.log(error);
});
this.state = {
client,
message: [''],
messageToSend:'',
isConnected: false,
pic_flag:''
}
}
connect(client){
return client.connect({
useSSL: true
})
.then(() => {
//订阅
client.subscribe('pic');
client.subscribe('dx');
})
}
onConnect = () => {
const { client } = this.state;
client.subscribe('pic');
client.subscribe('dx');
this.pushText('connected');
};
pushText = entry => {
const { message } = this.state;
this.setState({ message: [...message, entry] });
};
onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:"+responseObject.errorMessage);
}
}
onMessageArrived(message) {
//console.log("onMessageArrived:"+message.payloadString);
// var topic = message.destinationName;
//
// if(topic != "pic")
// {
// //console.log("onMessageArrived:"+message.payloadString);
// }
}
componentWillMount(){
}
//发送消息
sendMessage(){
var message = new Message(this.state.messageToSend);
//发送消息的标题
message.destinationName = "dx";
if(this.state.isConnected){
this.state.client.send(message);
}else{
this.connect(this.state.client)
.then(() => {
console.log('connect!');
this.state.client.send(message);
this.setState({error: '', isConnected: true});
})
.catch((error)=> {
console.log(error);
this.setState({error: error});
});
}
}
cmd_up()
{
location_f = location_f + 1;
if(location_f >= 9)
location_f = 9;
this.sendCmd();
}
cmd_down()
{
location_f = location_f - 1;
if(location_f <= 1)
location_f = 9;
this.sendCmd();
}
cmd_right()
{
location_x = location_x + 1;
if(location_x >= 9)
location_x = 9;
this.sendCmd();
}
cmd_left()
{
location_x = location_x - 1;
if(location_x <= 1)
location_x = 1;
this.sendCmd();
}
//发送控制命令
sendCmd(){
var message;
//控制指令
Str_Location = 'run -f ' + location_f + ' -x ' + location_x;
message = new Message(Str_Location);
//消息的标题
message.destinationName = "servo";
if(this.state.isConnected){
this.state.client.send(message);
}else{
this.connect(this.state.client)
.then(() => {
console.log('connect!');
this.state.client.send(message);
this.setState({error: '', isConnected: true});
})
.catch((error)=> {
console.log(error);
this.setState({error: error});
});
}
}
//页面渲染
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
欢迎使用霄哥APP!
</Text>
<Text style={styles.instructions}>
Message: {this.state.message.join(' --- ')}
</Text>
<Text style={{color: 'red'}}>
{this.state.error}
</Text>
{this.state.isConnected ?
<Text style={{color: 'green'}}>
已连接
</Text> : null
}
<TextInput
value={this.state.messageToSend}
onChangeText={(value => this.setState({messageToSend: value}))}
placeholder="message"
style={styles.input}
/>
<Button onPress={this.sendMessage.bind(this)} title="发送消息" />
<View style={{height: 50, flex: 1, flexDirection: 'row'}}>
<Button onPress={this.cmd_up.bind(this)} title="向上" />
<Button onPress={this.cmd_down.bind(this)} title="向下" />
<Button onPress={this.cmd_left.bind(this)} title="向左" />
<Button onPress={this.cmd_right.bind(this)} title="向右" />
</View>
<Image
style={{
width: 320,
height: 300,
resizeMode: 'contain',
}}
source={{uri: `data:image/gif;base64,${base64Icon}`}}
/>
</View>
);
}
}
const styles = StyleSheet.create({
input:{
width: 300
},
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
});
Demo版运行界面如图: