新玩具-企业微信机器人

这个机器人其实蛮久前就做好了,现在才写了点分享出来。 最近企业微信不断地开放了机器人的接口,所以我想想拿来做一些开发工具集成也是挺不错的,顺便也是为了继续熟悉一下 Rust 的编程习惯。 那么这次就大量使用 futures 来实现这个机器人的接口服务,这也是即将到来的无栈协程语法糖 await 的基石。

JUST PRACTICE

蛮久前入门了一下 Rust 语言。它的设计模型非常地吸引C/C++的开发者。但是学习语言嘛还是要练习一下,之前也用它给我们项目写了个命令行小工具。这回拿来写个小型的服务器程序吧。

Rust 的生态还处于非常初级的阶段。很多组件和库都处于开发中和设计变更的阶段,比起golang来,很多功能库都没有。 服务器编程本身特别注重高并发能力和,高性能。和原来很多客户端程序的思路是不太一样的。所以本来想等新的Futures和await和2.0版本的宏机制完成再搞。而老的Futures库由于即将移入核心库,在crates.io上下架了。现在似乎很多Rust的库都按Tokio的的模式来,于是我看了一下基于Futures的多路复用IO库Tokio的文档来练习一下这个小服务器程序。

之前我的域名只有owent.net和www.owent.net买了SSL证书,现在有letsencrypt可以拿到免费的SSL签证,就稍微花了点时间把我的域名的其他部分接入了letsencrypt签证系统。另外根据其他人的一些配置建议,提高了HTTPS的安全性配置和性能配置(主要是缓存)。另外原本我的blog就已经启用了spdy,然而现在新版本的nginx1.10)已经release,原先的spdy模块被取消,新增了http/2模块。但是直接换nginx掉包是不行滴(后面有说原因),所以顺带自己处理了一下HTTP/2和nginx新版本的问题。

并且也对公司里的域名和webserver也这么搞了一下。全面启用HTTPS。

接入letsencrypt

letsencrypt是Mozilla发起的一个提倡大家用加密的HTTP连接的项目,它允许大家申请到免费的SSL证书,用于HTTPS的证书认证。并且现在它的CA已经被大部分浏览器所接受。我这里本地Win10里使用的IE11,Edge,Firefox 46,Chrome 50全部都能认证通过了。当然手机上也可以。

最近看了点typescript的东西,加上以前看过的一点点Node.js,所以就想把他们系统地整理一下。

Javascript

这玩意搞过Web开发的应该都知道吧,Javascript的语法我就不废话了,挺简单的。这里总结几个Javascript的核心机制部分吧。

现在的web的js开发很方便啊,但是碰到iframe里的东西还是不方便看到变量的内容,所以就写了这么个看json内容的玩意,还可以当控制台输出用。

很简单,有需要以后开发新功能

/** 
 * Show json in a new page.(For debug)
 *
 * Licensed under the MIT or GPL Version 3 licenses.
 * @version 1.3
 * @author OWenT
 * @link http://www.owent.net
 * @history 
 * 		2012.12.27 
 * 			1. 改进JSON内对象循环引用时的导致的栈溢出问题
 * 			2. 引入层级路径
 * 			3. 引入锚点
 */
 
 /**
  * Object转为字符串
  * @param {Object} json Object对象 
  * @param {Number} tab 缩进数量
  * @param {Object} rules 应用规则
  * @param {String} path 当前路径
  * @return 生成的HTML
  */
function json2String(json, tab, rules, path) {
    var tabStr = "", singleTab = "    ", isClear = false;
    var txt = "";
    
    if (!rules) {
        rules = {
            id: "__json2string_process" + (new Date).getTime().toString() + (json2String.baseIndex ++),
            objs: []
        };
        isClear = true;
    }
    
    tab = tab || 1;
    if (!path) {
        path = "{ROOT}";
        txt += " ";
    }
    
    for (var i = 0; i < tab; i ++) {
        tabStr += singleTab;
    }
    
    if (!json && json !== 0) {
        txt += 'null';
    } else if (typeof(json) == "object") {
        var prefix = '{', suffix = '}';
        try {		
            if (toString.call(json).match(/array/i)) {
                prefix = '[';
                suffix = ']';
            }
        } catch(e) {
            // hoho ...
        }
        
        if (json[rules.id]) {
            txt += prefix + "此处引用 " + 
                json[rules.id] + "" + suffix;
            return txt;
        }
        json[rules.id] = path;
        rules.objs.push(json);
        
        txt += prefix + "
\r\n"; var first = true; for (var key in json) { if (key == rules.id) continue; if (first) first = false; else txt += ",
\r\n"; txt += tabStr + " " + "" + key + " : " + json2String(json[key], tab + 1, rules, path + "." + key); } txt += "
\r\n" + tabStr.substr(0, tabStr.length - singleTab.length) + suffix; } else if (typeof(json) == "string") { txt += '"' + json + '"'; } else if (typeof(json) == "number") { txt += '' + json + ''; } else if (typeof(json) == "function") { txt += '' + json + ''; } else { txt += json.toString(); } if (isClear) { for (var i = 0; i < rules.objs.length; ++ i) { delete rules.objs[i][rules.id]; } rules.objs = []; } return txt; } function showJson(json, title, windowName, dlg_opt) { json2String.baseIndex = json2String.baseIndex || 0; title = title || "Json viewer"; windowName = windowName || "result" + (new Date()).toGMTString(); if (window.jQuery && jQuery.fn && jQuery.fn.dialog) { $("
").append(json2String(json)).css({ "text-align": "left" }).dialog($.extend({ "modal": false, "title": title, "width": 640, "height": 480, "buttons": { "关闭": function() { $( this ).dialog( "close" ); } } }, dlg_opt)); } else { var wnd = window.open("about:blank", "_blank", "height=600, width=800, toolbar=no, menubar=no, resizable=yes, location=no, status=no", true); if (!wnd) alert("窗口被拦截!"); wnd.document.write("" + title + "" + json2String(json) + ""); } return wnd; }
  1. 更新对不同类型着色
  2. 如果载入了jQuery UI 则使用jQuery UI的Dialog打开,用于解决嵌套iframe时浏览器拦截问题
  3. 解决Object循环引用时栈溢出问题,同时增加引用的指向锚点

Licensed under the MIT or GPL Version 3 licenses.

这是学校USRP项目需要而写的一个类,但是既然写出来了,以后也可能用到,就共享出来吧。

这个类用于解析网页URL的QueryString参数,或者也可以当做操作一些其他设置的类库。

本类库支持任意类型的值的记录,支持JSON语法,支持类似“a=b&c=d”作为设置参数,支持对数组和JSON的转换。