let ROSLIB = require('roslib');
import intl from 'react-intl-universal';
import { isLegal } from './message.type'
import { LocalStorage } from './localStorage'
import { notification } from 'antd';
let instance = null;
let reconnect = false;
/**
* 与 ROS 进行 pub/sub 通讯工具
* 单例模式
*
* 任意位置 用法:
* import { Networking } from './network'
* let network = new Networking();
* //发布消息
* network.publish(……);
*
* 订阅消息
* let sub = network.listen('/add_two_ints','rospy_tutorials/AddTwoInts',(name,data)=>{
* console.log(name,data)
* sub.unsubscribe();
* })
*
*
*/
export class Networking {
constructor() {
if (!instance) {
let t = this;
let localStorage = new LocalStorage();
let ip = localStorage.getItem("ip");
instance = new ROSLIB.Ros({
url: 'ws://' + ip + ':9090'
});
instance.on('connection', function () {
console.log('Connected to websocket server.');
instance.isConnect = true;
notification.close('closeMsg1');
notification.close('closeMsg2');
reconnect = false;
notification['success']({
message: intl.get('SUCCESS'),
description: intl.get('CONNECTSUCCESS'),
});
});
instance.on('error', function (error) {
instance.isConnect = false;
if (reconnect === false) {
notification['error']({
key:'closeMsg1',
message: intl.get('FAIL'),
description: intl.get('CONNECTFAIL'),
duration:null,
});
reconnect = true;
}
});
instance.on('close', function () {
instance.isConnect = false;
// 断开重连
instance.connect('ws://' + ip + ':9090');
if (reconnect === false) {
notification['error']({
key:'closeMsg2',
message: intl.get('FAIL'),
description: intl.get('CONNECTFAIL'),
duration:null,
});
reconnect = true;
}
});
}
}
/**
* 获取连接状态
* @returns {boolean}
*/
getIsConnect = () => {
return instance && instance.isConnect;
}
/**
* 发布消息
* @param topic 消息 topic
* @param messageType 消息类型 ,例如 /cmd_vel
* @param message 消息内容
* @returns {boolean} 发送状态
*/
publish = (topic, messageType, message) => {
if (!isLegal(messageType)) {
console.error(`publish 不存在 ${messageType} 这样的类型`);
return false;
}
let type = new ROSLIB.Topic({
ros: instance,
name: topic,
messageType: messageType
});
let value = new ROSLIB.Message(message);
type.publish(value);
return true;
}
/**
* 订阅消息
* @param topic 消息 topic
* @param messageType 消息类型 ,例如 /cmd_vel
* @param listener 接收到消息后的回调
* @returns {sub} 返回 sub,由用户决定何时取消订阅 sub.unsubscribe();
*/
listen = (topic, messageType, listener) => {
if (!isLegal(messageType)) {
console.error(`listener 不存在 ${messageType} 这样的类型`);
return false;
}
let sub = new ROSLIB.Topic({
ros: instance,
name: topic,
messageType: messageType
});
sub.subscribe(function (message) {
// console.log('Received message on ' + sub.name + ': ' + message);
listener(sub.name, message);
});
return sub;
}
/**
* 调用 service
* @param topic
* @param messageType
* @param reqParams 调用参数
* @param resListener 服务器响应后的回调,传入响应结果
*/
callService = (topic, messageType, reqParams, resListener) => {
let client = new ROSLIB.Service({
ros: instance,
name: topic,
serviceType: messageType
});
let request = new ROSLIB.ServiceRequest(reqParams);
client.callService(request, function (result) {
console.log('Result for service call on ', client.name, ': ', result);
resListener(result);
});
}
/**
* 发布一个 service (本项目可能用不到)
* @param topic
* @param messageType
* @param serviceListener
*
* serviceListener的用法如下:
* function (request , response) {
console.log('Received service request on ' + service.name + ': ' + request.data);
response['success'] = true;
response['message'] = 'Set successfully';
return true;
}
* 传入两个参数:request 和 response
* 最后给 response 赋值,并 return ,
*/
adsService = (topic, messageType, serviceListener) => {
let service = new ROSLIB.Service({
ros: instance,
name: topic,
serviceType: messageType
});
service.advertise(serviceListener);
}
/**
* 调用 action
* @param topic
* @param messageType
* @param goalParams action goalParams
* @param listeners actionListener 消息回调,可选 `feedbackListener`, `statusListener`, `resultListener`
* @return client - ActionClient 对象实例,可用于取消action `client.cancel()`,以及注销订阅 `client.dispose()`
*/
action = (topic, messageType, goalParams, listeners) => {
if (!listeners) {
listeners = {};
}
let feedbackListener = listeners.feedbackListener;
let statusListener = listeners.statusListener;
let resultListener = listeners.resultListener;
//create actionClient
let client = new ROSLIB.ActionClient({
ros: instance,
serverName: topic,
actionName: messageType
});
// Create a goal.
let goal = new ROSLIB.Goal({
actionClient: client,
goalMessage: goalParams
});
//subscribe actionlisteners
if (feedbackListener && typeof feedbackListener == 'function') {
goal.on('feedback', function (feedback) {
feedbackListener(feedback);
});
}
if (statusListener && typeof statusListener == 'function') {
goal.on('status', function (status) {
statusListener(status);
})
}
if (resultListener && typeof resultListener == 'function') {
goal.on('result', function (result) {
resultListener(result)
});
}
goal.send();
return client;
}
}
参考: