教你写一个web远程控制小工具
惯例先上图

晚上躺床上了,发现忘关电脑了,又不想起来关,来用手机控制电脑多好,百度了下,果然一大把。哈,我自己为什么不自己也实现个呢,任意的自己diy。Just do it。
如果不想看如何实现,那么直接用下面的吧:
web操控端:http://smallyard.cn/jobhub/
控制端jar包: http://files.cnblogs.com/files/smallyard/jobhub-client.rar
运行:java -jar joghub-client.jar [你的密码]
一、 网络通信
二、 客户端
客户端的主要任务是接受命令并执行命令,执行命令我通过调用命令行来执行。
命令监听和发送类,主要是调用云吧的API。
/**
* 任务监听者
*/
public class JobHandler {
private static final String APP_KEY = "567392ee4407a3cd028aacf6";
private static MqttAsyncClient mqttAsyncClient;
private static String listenTopic;
static {
try {
mqttAsyncClient = MqttAsyncClient.createMqttClient(APP_KEY);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 监听开始
*/
public static void start(final String topic) {
listenTopic = topic;
connect();
listen();
}
public static void publish(String msg) {
try {
mqttAsyncClient.publish(listenTopic + APP_KEY, msg.getBytes(), 1, false, null, new IMqttActionListener() {
public void onFailure(IMqttToken arg0, Throwable arg1) {
System.out.println("消息返回失败");
}
public void onSuccess(IMqttToken arg0) {
System.out.println("消息返回成功");
}
});
} catch (MqttException e) {
e.printStackTrace();
}
}
// 连接服务器
private static void connect() {
try {
mqttAsyncClient.connect(new IMqttActionListener() {
public void onSuccess(IMqttToken arg0) {
System.out.println("连接服务器成功.");
subscribe();
}
public void onFailure(IMqttToken arg0, Throwable arg1) {
System.out.println("连接服务器失败");
}
});
} catch (MqttException e) {
e.printStackTrace();
}
}
private static void subscribe() {
try {
mqttAsyncClient.subscribe(listenTopic, 1, null, new IMqttActionListener() {
public void onSuccess(IMqttToken asyncActionToken) {
System.out.println("成功监听主题: " + StringUtils.join(asyncActionToken.getTopics(), ","));
}
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
System.err.println("监听失败");
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
// 监听消息
private static void listen() {
mqttAsyncClient.setCallback(new MqttCallback() {
public void connectionLost(Throwable throwable) {
}
public void messageArrived(String topic, MqttMessage message) throws Exception {
String cmd = new String(message.getPayload());
System.out.println("接收到命令:" + cmd);
Thread thread = new Thread(new JobExecutor(cmd));
thread.start();
}
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
}
});
}
}
命令执行类,调用命令行执行命令,再调用云吧API来发送执行结果。
/**
* 任务执行
*/
public class JobExecutor implements Runnable {
private String cmd;
public JobExecutor(String cmd) {
this.cmd = cmd;
}
public void run() {
BufferedReader br = null;
try {
Process p = Runtime.getRuntime().exec(this.cmd);
br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
System.out.println(sb.toString());
JobHandler.publish(sb.toString());
} catch (Exception e) {
e.printStackTrace();
JobHandler.publish("执行失败");
} finally {
if (br != null) {
try {
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
三、 WEB端
web端的主要任务是发送命令,并接受命令执行的结果。
var hasConnect = false;
var appkey = "567392ee4407a3cd028aacf6";
var yunba = new Yunba({server: 'sock.yunba.io', port: 3000, appkey: appkey});
// 连接服务器并发送消息
function connect(cmd, topic) {
yunba.init(function (success) {
if (success) {
// 连接服务器
yunba.connect_by_customid('jobhub-web', function (success, msg, sessionid) {
if (success) {
hasConnect = true;
console.log('你已成功连接到消息服务器,会话ID:' + sessionid);
// 监听回传消息
yunba.subscribe({'topic': topic + appkey},
function (success, msg) {
if (success) {
console.log('你已成功订阅频道' + topic + appkey);
yunba.set_message_cb(showMsg);
send(cmd, topic);
} else {
console.log(msg);
}
});
} else {
console.log(msg);
}
});
}
});
}
// 发送消息
function send(cmd, topic) {
yunba.publish({'topic': topic, 'msg': cmd},
function (success, msg) {
if (success) {
console.log('消息发布成功');
} else {
console.log(msg);
}
});
}
// 显示回传消息
function showMsg(data){
var msg = data.msg;
console.log('Topic:' + data.topic + ',Msg:' + msg);
// 替换回车
msg = msg.replace(/\r\n|\n/g,"<br/>");
// 替换执行失败
msg = msg.replace("执行失败", "<span style='color:red;'>执行失败</span>");
// 显示
var $divMsg = $("#div_msg");
$divMsg.append("<p>" + msg + "</p>");
// 滚动到最下方
$divMsg.scrollTop($divMsg[0].scrollHeight );
}
$("#btnSubmit").click(function () {
var $inputCmd = $("#inputCmd");
var $inputTopic = $("#inputTopic");
var $spanInfo = $("#spanInfo");
var cmd = $inputCmd.val();
var topic = $inputTopic.val();
if (!cmd) {
$spanInfo.text("命令不能为空");
return;
}
if (!topic) {
$spanInfo.text("密码不能为空");
return;
}
if (hasConnect) {
send(cmd, topic);
} else {
connect(cmd, topic)
}
$inputCmd.val("").focus();
// $inputTopic.val("");
$spanInfo.text("已发送命令:" + cmd);
});
// 绑定回车事件
$(document).keydown(function(e){
if(e.keyCode==13){
$("#btnSubmit").click();
}
});
四、 总结
想着很复杂,其实实现起来很简单的。
源码发布在github:
https://github.com/smallyard/smallyard
https://github.com/smallyard/jobhub-client
大家可以自己拿走扩充成自己喜欢的远程控制。
教你写一个web远程控制小工具的更多相关文章
- 利用 Python 写一个颜值测试小工具
我们知道现在有一些利用照片来测试颜值的网站或软件,其实使用 Python 就可以实现这一功能,本文我们使用 Python 来写一个颜值测试小工具. 很多人学习python,不知道从何学起.很多人学习p ...
- 【移动端debug-6】如何做一个App里的web调试小工具
原文链接:如何做一个App里的web调试小工具 我们知道现在hybrid app非常流行,在这样的app里,h5页面是应用非常广泛的.相对于以往在pc端开发的网页,放在app里的网页由于无法直接使用桌 ...
- 只有20行Javascript代码!手把手教你写一个页面模板引擎
http://www.toobug.net/article/how_to_design_front_end_template_engine.html http://barretlee.com/webs ...
- 使用Node.js原生API写一个web服务器
Node.js是JavaScript基础上发展起来的语言,所以前端开发者应该天生就会一点.一般我们会用它来做CLI工具或者Web服务器,做Web服务器也有很多成熟的框架,比如Express和Koa.但 ...
- 使用node.js 文档里的方法写一个web服务器
刚刚看了node.js文档里的一个小例子,就是用 node.js 写一个web服务器的小例子 上代码 (*^▽^*) //helloworld.js// 使用node.js写一个服务器 const h ...
- #使用abp框架与vue一步一步写我是月老的小工具(2) 后台搭建初体验
#使用abp框架与vue一步一步写我是月老的小工具(2) 后台搭建初体验 一.续上前言 关于这个小玩意的产品思考,假设我暂时把他叫我是月老热心人 这是一个没有中心的关系链,每个人进入以后都是以自己为中 ...
- 用C写一个web服务器(二) I/O多路复用之epoll
.container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...
- java 写一个JSON解析的工具类
上面是一个标准的json的响应内容截图,第一个红圈”per_page”是一个json对象,我们可以根据”per_page”来找到对应值是3,而第二个红圈“data”是一个JSON数组,而不是对象,不能 ...
- 半个小时教你写一个装(bi)逼(she)之地图搜租房
半个小时教你写一个装(bi)逼(she)之地图搜租房 首先需要一个Python3环境,怎么准备我就不多说了,实在不会的出门右转看一下廖雪峰老师的博客. HTML部分 代码来自:高德API+Python ...
随机推荐
- 常用的JAVA集合讲解
java.util包中包含了一系列重要的集合类,而对于集合类,主要需要掌握的就是它的内部结构,以及遍历集合的迭代模式. 接口:Collection Collection是最基本的集合接口,一个Coll ...
- proxool 连接池警告分析:appears to have started a thread named [HouseKeeper] but has failed to stop it
1. 问题:日志中出现下面的警告: 警告: The web application [ROOT] appears to have started a thread named [HouseKeeper ...
- jstl 中<c:forEach />标签
<c:forEach>标签有如下属性: 属性 描述 是否必要 默认值 items 要被循环的信息 否 无 begin 开始的元素(0=第一个元素,1=第二个元素) 否 0 end 最后一个 ...
- strlen和sizeof的区别
1.sizeof操作符的结果类型是size_t,它在头文件中typedef为unsigned int类型.该类型保证能容纳实现所建立的最大对象的字节大小. 2.sizeof是算符,strlen是函 ...
- 关于Leetcode上二叉树的算法总结
二叉树,结构很简单,只是比单链表复杂了那么一丢丢而已.我们先来看看它们结点上的差异: /* 单链表的结构 */ struct SingleList{ int element; struct Singl ...
- Tomcat免安装配置2
Tomcat 是一款优秀的JSP/Servlet容器,最初由SUN开发,后来被贡献给了Apache社区.Tomcat现在的版本已到6.Tomcat6实现了Servlet2.5和JSP2.1规范.针对w ...
- Microsoft.Bcl.Build 1.0.10 稳定版发布
Microsoft.Bcl.Build 1.0.10 稳定版发布 解决了之前 1.0.8 在未下载相应的Nuget Package 的情况下项目无法加载的情况 但由于 Microsoft.Net.Ht ...
- [转]ASP.NET MVC IOC 之AutoFac攻略
本文转自:http://www.cnblogs.com/WeiGe/p/3871451.html 一.为什么使用AutoFac? 之前介绍了Unity和Ninject两个IOC容器,但是发现园子里用A ...
- .Net程序员之Python基础教程学习----列表和元组 [First Day]
一. 通用序列操作: 其实对于列表,元组 都属于序列化数据,可以通过下表来访问的.下面就来看看序列的基本操作吧. 1.1 索引: 序列中的所有元素的下标是从0开始递增的. 如果索引的长度的是N,那么所 ...
- app微信支付(一) - 微信支付基本业务流程解析
想必微信支付是现在很多朋友离不开的一个功能,不论是扫描支付还是公众号支付或者app端支付,基本的思路都是一样的,之前做过支付宝支付以及中国移动支付接口,这几天花时间讲讲微信支付吧 先看一下微信支付的时 ...