教你写一个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 [你的密码]

一、 网络通信

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

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

它有java和JavaScript的API

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

二、 客户端

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

命令监听和发送类,主要是调用云吧的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

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

时间: 2024-08-07 02:21:58

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

小程序初体验:手把手教你写出第一个小程序(一)

本文笔者将根据quick start中的范例代码,带大家简单地剖析一下小程序的运行方式,并介绍小程序开发中一些通用的特性,带着大家一步步写出自己的小程序. 适用对象:前端初学者,对小程序开发感兴趣者 tips:由于笔者也是一位前端菜鸟,所以尽量用简单直白的语言为大家讲解,如有说的不到位的地方,还望多多指教. 吊了我们一年胃口的小程序终于和大家见面了.经过了一天的发酵,小程序已经成为了今天的超级头条(汪汪哭晕在厕所). 经历了一天媒体对小程序的狂轰滥炸,相信大家对于小程序一定充满了好奇.与其跟风转

如何给ss bash 写一个 WEB 端查看流量的页面

由于刚毕业的穷大学生,和朋友合租了一台服务器开了多个端口提供 ss 服务,懒得配置 ss-panel,就使用了 ss-bash 来监控不同端口的流量,但每次都要等上服务器才能看到流量使用情况,很麻烦,于是就写了个简单的页面来提供 WEB 访问,具体内容一起通过本文学习吧 由于刚毕业的穷大学生,和朋友合租了一台服务器开了多个端口提供 ss 服务,懒得配置 ss-panel,就使用了 ss-bash 来监控不同端口的流量,但每次都要等上服务器才能看到流量使用情况,很麻烦,于是就写了个简单的页面来提供

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

刚刚看了node.js文档里的一个小例子,就是用 node.js 写一个web服务器的小例子 上代码 (*^▽^*) //helloworld.js// 使用node.js写一个服务器 const http=require('http'); const hostname='127.0.0.1' const port=3000; const server = http.createServer((req,res)=>{ res.statusCode=200; res.setHeader('Cont

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

.container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .container::before,.container::after { content: " "; display: table } .container::after { clear: both } .container::before,.container::after { content:

一起写一个 Web 服务器

导读: 本系列深入浅出的讲述了如何用 Python 从 0 开始,写一个 web 服务器,并让其与业界流行的 web 框架协同工作,最后还进一步完善了开头的 web 服务器 demo,让其可以支持多并发请求的处理,并解决了过程当中遇到的"僵尸进程"等一系列 socket/网络编程 中的常见问题,图文并茂.循序渐进,是篇非常不错的教程,对了解整个 Web 编程理论相当有帮助,推荐一看. 作者:伯乐在线 - 高世界 翻译 1.什么是 Web 服务器,以及怎样工作的? 一起写一个 Web 服

Python3的tkinter写一个简单的小程序

一.这个学期开始学习python,但是看了python2和python3,最后还是选择了python3 本着熟悉python的原因,并且也想做一些小程序来增加自己对python的熟练度.所以写了一个简单的程序,这个小程序实现了basa64.base32的加解码.并且添加了一个md5生成的功能.ps:觉得python开发也挺好玩的... 二.运行程序截图: 上面的就是程序的整体界面了.. 三.程序的设计: 源代码就在下面贴图了,并且需要的文档可以--------------搜索吧..... imp

如何写一个Web服务器

最近两个月的业余时间在写一个私人项目,目的是在Linux下写一个高性能Web服务器,名字叫Zaver.主体框架和基本功能已完成,还有一些高级功能日后会逐渐增加,代码放在了github.Zaver的框架会在代码量尽量少的情况下接近工业水平,而不像一些教科书上的toy server为了教原理而舍弃了很多原本server应该有的东西.在本篇文章中,我将一步步地阐明Zaver的设计方案和开发过程中遇到的困难以及相应的解决方法. 为什么要重复造轮子 几乎每个人每天都要或多或少和Web服务器打交道,比较著名

大神手把手教你写一个页面模板引擎,只需20行Javascript代码!

只用20行Javascript代码就写出一个页面模板引擎的大神是AbsurdJS的作者,下面是他分享的全文,转需. 不知道你有木有听说过一个基于Javascript的Web页面预处理器,叫做AbsurdJS.我是它的作者,目前我还在不断地完善它.最初我只是打算写一个CSS的预处理器,不过后来扩展到了CSS和HTML,可以用来把Javascript代码转成CSS和HTML代码.当然,由于可以生成HTML代码,你也可以把它当成一个模板引擎,用于在标记语言中填充数据. 于是我又想着能不能写一些简单的代

Python学习之旅:用Python制作一个打字训练小工具

一.写在前面 说道程序员,你会想到什么呢?有人认为程序员象征着高薪,有人认为程序员都是死肥宅,还有人想到的则是996和 ICU. 别人眼中的程序员:飞快的敲击键盘.酷炫的切换屏幕.各种看不懂的字符代码. 然而现实中的程序员呢?对于很多程序员来说,没有百度和 Google 解决不了的问题,也没有 ctrl + c 和 ctrl + v 实现不了的功能. 那么身为一个程序员,要怎么让自己看起来更加“专业”呢?答案就是加快自己的打字速度了,敲的代码可能是错的,但这个13却是必须装的! 然而还是有不少人