惯例先上图

晚上躺床上了,发现忘关电脑了,又不想起来关,来用手机控制电脑多好,百度了下,果然一大把。哈,我自己为什么不自己也实现个呢,任意的自己diy。Just do it。

如果不想看如何实现,那么直接用下面的吧:

web操控端:http://smallyard.cn/jobhub/

控制端jar包: http://files.cnblogs.com/files/smallyard/jobhub-client.rar

运行:java -jar joghub-client.jar [你的密码]

一、 网络通信

网络通信模块,如果自己做的话,也不是很难,就是做好了,需要买服务器来部署,这还是算了吧,为了自己玩一玩而花钱,这种事还是不干,那就用第三方的好了。

上网时,偶然发现的一个云吧,提供消息发送和消息订阅的服务。我们只需要用它把我们的控制端web和客户端监听连接起来就行了。

它有java和JavaScript的API

这时想起百度的产品里有个API store,搜索了下,果然找到了合适的接口。

二、 客户端

客户端的主要任务是接受命令并执行命令,执行命令我通过调用命令行来执行。

命令监听和发送类,主要是调用云吧的API。

  1. /**
  2. * 任务监听者
  3. */
  4. public class JobHandler {
  5.  
  6. private static final String APP_KEY = "567392ee4407a3cd028aacf6";
  7.  
  8. private static MqttAsyncClient mqttAsyncClient;
  9.  
  10. private static String listenTopic;
  11.  
  12. static {
  13. try {
  14. mqttAsyncClient = MqttAsyncClient.createMqttClient(APP_KEY);
  15. } catch (Exception e) {
  16. e.printStackTrace();
  17. }
  18. }
  19.  
  20. /**
  21. * 监听开始
  22. */
  23. public static void start(final String topic) {
  24. listenTopic = topic;
  25. connect();
  26. listen();
  27. }
  28.  
  29. public static void publish(String msg) {
  30. try {
  31. mqttAsyncClient.publish(listenTopic + APP_KEY, msg.getBytes(), 1, false, null, new IMqttActionListener() {
  32.  
  33. public void onFailure(IMqttToken arg0, Throwable arg1) {
  34. System.out.println("消息返回失败");
  35. }
  36.  
  37. public void onSuccess(IMqttToken arg0) {
  38. System.out.println("消息返回成功");
  39. }
  40. });
  41. } catch (MqttException e) {
  42. e.printStackTrace();
  43. }
  44. }
  45.  
  46. // 连接服务器
  47. private static void connect() {
  48. try {
  49. mqttAsyncClient.connect(new IMqttActionListener() {
  50. public void onSuccess(IMqttToken arg0) {
  51. System.out.println("连接服务器成功.");
  52. subscribe();
  53. }
  54.  
  55. public void onFailure(IMqttToken arg0, Throwable arg1) {
  56. System.out.println("连接服务器失败");
  57. }
  58. });
  59. } catch (MqttException e) {
  60. e.printStackTrace();
  61. }
  62. }
  63.  
  64. private static void subscribe() {
  65. try {
  66. mqttAsyncClient.subscribe(listenTopic, 1, null, new IMqttActionListener() {
  67. public void onSuccess(IMqttToken asyncActionToken) {
  68. System.out.println("成功监听主题: " + StringUtils.join(asyncActionToken.getTopics(), ","));
  69. }
  70.  
  71. public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
  72. System.err.println("监听失败");
  73. }
  74. });
  75. } catch (Exception e) {
  76. e.printStackTrace();
  77. }
  78. }
  79.  
  80. // 监听消息
  81. private static void listen() {
  82. mqttAsyncClient.setCallback(new MqttCallback() {
  83. public void connectionLost(Throwable throwable) {
  84.  
  85. }
  86.  
  87. public void messageArrived(String topic, MqttMessage message) throws Exception {
  88. String cmd = new String(message.getPayload());
  89. System.out.println("接收到命令:" + cmd);
  90. Thread thread = new Thread(new JobExecutor(cmd));
  91. thread.start();
  92. }
  93.  
  94. public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
  95.  
  96. }
  97. });
  98. }
  99. }

命令执行类,调用命令行执行命令,再调用云吧API来发送执行结果。

  1. /**
  2. * 任务执行
  3. */
  4. public class JobExecutor implements Runnable {
  5.  
  6. private String cmd;
  7.  
  8. public JobExecutor(String cmd) {
  9. this.cmd = cmd;
  10. }
  11.  
  12. public void run() {
  13. BufferedReader br = null;
  14. try {
  15. Process p = Runtime.getRuntime().exec(this.cmd);
  16. br = new BufferedReader(new InputStreamReader(p.getInputStream()));
  17. String line;
  18. StringBuilder sb = new StringBuilder();
  19. while ((line = br.readLine()) != null) {
  20. sb.append(line).append("\n");
  21. }
  22. System.out.println(sb.toString());
  23. JobHandler.publish(sb.toString());
  24. } catch (Exception e) {
  25. e.printStackTrace();
  26. JobHandler.publish("执行失败");
  27. } finally {
  28. if (br != null) {
  29. try {
  30. br.close();
  31. } catch (Exception e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. }
  36. }
  37. }

三、 WEB端

web端的主要任务是发送命令,并接受命令执行的结果。

  1. var hasConnect = false;
  2. var appkey = "567392ee4407a3cd028aacf6";
  3. var yunba = new Yunba({server: 'sock.yunba.io', port: 3000, appkey: appkey});
  4.  
  5. // 连接服务器并发送消息
  6. function connect(cmd, topic) {
  7. yunba.init(function (success) {
  8. if (success) {
  9. // 连接服务器
  10. yunba.connect_by_customid('jobhub-web', function (success, msg, sessionid) {
  11. if (success) {
  12. hasConnect = true;
  13. console.log('你已成功连接到消息服务器,会话ID:' + sessionid);
  14. // 监听回传消息
  15. yunba.subscribe({'topic': topic + appkey},
  16. function (success, msg) {
  17. if (success) {
  18. console.log('你已成功订阅频道' + topic + appkey);
  19. yunba.set_message_cb(showMsg);
  20. send(cmd, topic);
  21. } else {
  22. console.log(msg);
  23. }
  24. });
  25. } else {
  26. console.log(msg);
  27. }
  28. });
  29. }
  30. });
  31. }
  32.  
  33. // 发送消息
  34. function send(cmd, topic) {
  35. yunba.publish({'topic': topic, 'msg': cmd},
  36. function (success, msg) {
  37. if (success) {
  38. console.log('消息发布成功');
  39. } else {
  40. console.log(msg);
  41. }
  42. });
  43. }
  44.  
  45. // 显示回传消息
  46. function showMsg(data){
  47. var msg = data.msg;
  48. console.log('Topic:' + data.topic + ',Msg:' + msg);
  49.  
  50. // 替换回车
  51. msg = msg.replace(/\r\n|\n/g,"<br/>");
  52. // 替换执行失败
  53. msg = msg.replace("执行失败", "<span style='color:red;'>执行失败</span>");
  54.  
  55. // 显示
  56. var $divMsg = $("#div_msg");
  57. $divMsg.append("<p>" + msg + "</p>");
  58.  
  59. // 滚动到最下方
  60. $divMsg.scrollTop($divMsg[0].scrollHeight );
  61. }
  62.  
  63. $("#btnSubmit").click(function () {
  64. var $inputCmd = $("#inputCmd");
  65. var $inputTopic = $("#inputTopic");
  66. var $spanInfo = $("#spanInfo");
  67. var cmd = $inputCmd.val();
  68. var topic = $inputTopic.val();
  69. if (!cmd) {
  70. $spanInfo.text("命令不能为空");
  71. return;
  72. }
  73. if (!topic) {
  74. $spanInfo.text("密码不能为空");
  75. return;
  76. }
  77.  
  78. if (hasConnect) {
  79. send(cmd, topic);
  80. } else {
  81. connect(cmd, topic)
  82. }
  83.  
  84. $inputCmd.val("").focus();
  85. // $inputTopic.val("");
  86. $spanInfo.text("已发送命令:" + cmd);
  87. });
  88.  
  89. // 绑定回车事件
  90. $(document).keydown(function(e){
  91. if(e.keyCode==13){
  92. $("#btnSubmit").click();
  93. }
  94. });

  

四、 总结

想着很复杂,其实实现起来很简单的。

源码发布在github:

https://github.com/smallyard/smallyard

https://github.com/smallyard/jobhub-client

大家可以自己拿走扩充成自己喜欢的远程控制。

 

教你写一个web远程控制小工具的更多相关文章

  1. 利用 Python 写一个颜值测试小工具

    我们知道现在有一些利用照片来测试颜值的网站或软件,其实使用 Python 就可以实现这一功能,本文我们使用 Python 来写一个颜值测试小工具. 很多人学习python,不知道从何学起.很多人学习p ...

  2. 【移动端debug-6】如何做一个App里的web调试小工具

    原文链接:如何做一个App里的web调试小工具 我们知道现在hybrid app非常流行,在这样的app里,h5页面是应用非常广泛的.相对于以往在pc端开发的网页,放在app里的网页由于无法直接使用桌 ...

  3. 只有20行Javascript代码!手把手教你写一个页面模板引擎

    http://www.toobug.net/article/how_to_design_front_end_template_engine.html http://barretlee.com/webs ...

  4. 使用Node.js原生API写一个web服务器

    Node.js是JavaScript基础上发展起来的语言,所以前端开发者应该天生就会一点.一般我们会用它来做CLI工具或者Web服务器,做Web服务器也有很多成熟的框架,比如Express和Koa.但 ...

  5. 使用node.js 文档里的方法写一个web服务器

    刚刚看了node.js文档里的一个小例子,就是用 node.js 写一个web服务器的小例子 上代码 (*^▽^*) //helloworld.js// 使用node.js写一个服务器 const h ...

  6. #使用abp框架与vue一步一步写我是月老的小工具(2) 后台搭建初体验

    #使用abp框架与vue一步一步写我是月老的小工具(2) 后台搭建初体验 一.续上前言 关于这个小玩意的产品思考,假设我暂时把他叫我是月老热心人 这是一个没有中心的关系链,每个人进入以后都是以自己为中 ...

  7. 用C写一个web服务器(二) I/O多路复用之epoll

    .container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...

  8. java 写一个JSON解析的工具类

    上面是一个标准的json的响应内容截图,第一个红圈”per_page”是一个json对象,我们可以根据”per_page”来找到对应值是3,而第二个红圈“data”是一个JSON数组,而不是对象,不能 ...

  9. 半个小时教你写一个装(bi)逼(she)之地图搜租房

    半个小时教你写一个装(bi)逼(she)之地图搜租房 首先需要一个Python3环境,怎么准备我就不多说了,实在不会的出门右转看一下廖雪峰老师的博客. HTML部分 代码来自:高德API+Python ...

随机推荐

  1. Hessian 二进制RPC协议框架

    Hessian是一个由Caucho Technology开发的轻量级二进制RPC协议. 和其他Web服务的实现框架不同的是,Hessian是一个使用二进制轻量级的Web服务协议的框架,免除了许多附加的 ...

  2. SQL Server 2000 :选择许可模式及更改

    在SQL Server企业版中,有一个许可模式概念,有两种许可模式:“处理器许可证”和“每客户”模式.“处理器许可证”模式表示允许几个CPU运行SQL Server,“每客户”决定的是客户端连接数. ...

  3. [麦先生]TP3.2之微信开发那点事[基础篇](网页授权开发之小Demo)

    用户à 点击按钮进入授权页面并确认授权à 服务器返回code给开发者à 利用code,APPID,APPsecret组合数据请求API获取access_token和openidà 利用access_t ...

  4. MMORPG大型游戏设计与开发(part5 of net)

    上一部分将服务器的具体代码的实现介绍给了大家,想必大家也了解到了服务器处理一次消息的复杂度.如果大家能够将各个过程掌握清楚,就会发觉其实整个逻辑与交互过程是比较清晰的.那么服务器与服务器之间的通讯,其 ...

  5. java设计模式之抽象工厂模式

    上一篇文章(http://www.cnblogs.com/liaoweipeng/p/5768197.html)讲了简单工厂模式,但是简单工厂模式存在一定的问题,如果想要拓展程序,必须对工厂类进行修改 ...

  6. NOIP2000方格取数[DP]

    题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 ...

  7. guava 学习笔记 使用瓜娃(guava)的选择和预判断使代码变得简洁

    guava 学习笔记 使用瓜娃(guava)的选择和预判断使代码变得简洁 1,本文翻译自 http://eclipsesource.com/blogs/2012/06/06/cleaner-code- ...

  8. HB制作的app版本更新

    wgt下载成功,安装的时候报wgt包中的manifest.json文件的version必须要大于当前版本,所以每次提交wgt资源包的时候一定要记得大于当前的版本号

  9. web端通信技术

    1.web端通信技术:长连接.长轮询.websocket; 什么是长连接.长轮询? 就是客户端不停的向服务器发送请求以获取最新的数据信息.这里的“不停”其实是有停止的,只是我们人眼无法分辨是否停止,它 ...

  10. Js多国时间动态更新

    Js多国时间动态更新 点击下载