`
linxuexin
  • 浏览: 26969 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
社区版块
存档分类
最新评论

PHPRPC 2.1 的 ASP 服务器和客户端

阅读更多
经过 3 天的努力,终于把 ASP 的 PHPRPC 服务器和客户端写好了,为了充分利用已经写好的编码,ASP 的服务器和客户端都是用 JScript 实现的,里面调用了原来写好的 utf.js、base64.js、phpserializer.js、powmod.js 和 xxtea.js 这五个文件。ASP 版本的 PHPRPC 服务器和 PHP 版本的 PHPRPC 服务器端功能基本上一致,不过 ASP 版本的不支持输出重定向,也就是说如果远程函数中有用 Response.Write 输出的内容,在客户端是不能通过 output 参数得到的。这是由于 ASP 本身输出控制功能太弱造成的,另外,ASP 服务器端创建时,没有 debug 参数。ASP 服务器端发生的错误都是严重错误(没有警告和提示性错误)。ASP 客户端在初始化调用时,应使用绝对地址,而不能使用相对地址。

phprpc_server.js
/**
* @author      Ma Bingyao(andot@ujn.edu.cn)
* @copyright   CoolCode.CN
* @package     ASP_PHPRPC_SERVER
* @version     2.1
* @last_update 2006-06-12
* @link        http://www.coolcode.cn/?p=187
*
* Example usage:
*
* server.asp
* <%@ CodePage = 65001 %>
* <script runat="server" type="text/javascript" src="phprpc_server.js"></script>
* <%
* function add(a, b)
*     add = a + b
* end function
 
* function subtract(a, b)
*     subtract = a - b
* end function
* phprpc_server.create(Array('add', 'sub'));
* %>
*/
 
function addjsslashes(str, flag) {
    var test;
    if (flag == false) {
        test = /([\0-\037\042\047\134])/g;
    }
    else {
        test = /([\0-\037\042\047\134\177-\377])/g;
    }
    return str.replace(test, function ($1) {
        var s = $1.charCodeAt(0).toString(8);
        return '\\' + ((s.length == 1) ? "00" : ((s.length == 2) ? "0" : "")) + s;
    });
}
 
function getGMTDate(date) {
    var week = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
    return week[date.getUTCDay()] + ", " + date.toGMTString();
}
 
function IsEmpty(o) {
    if (typeof(o) == "object" && String(o) == "undefined") return true;
    return false;
}
 
function phprpc_server(functions) {
    Response.CodePage = 65001;
    Session.CodePage = 65001;
    var func, args, result, encrypt;
    var date = getGMTDate(new Date());
    Response.Buffer = true;
    Response.ContentType = "text/plain";
    Response.Charset = "utf-8";
    Response.AddHeader("X-Powered-By", "PHPRPC Server/2.1");
    Response.AddHeader("Date", date);
    Response.AddHeader("Last0Modified", date);
    Response.AddHeader("Cache-Control", "no-store, no-cache, must-revalidate");
    Response.AddHeader("Cache-Control", "pre-check=0, post-check=0, max-age=0");
    Response.AddHeader("Content-Encoding", "none");
    if (functions.constructor == Array) {
        this.functions = functions;
    }
    else if (functions.constructor == VBArray) {
        this.functions = functions.toArray();
    }
    else {
        this.functions = [functions];
    }
    this.encode = true;
    if (!IsEmpty(Request('phprpc_encode'))) {
        this.encode = String(Request('phprpc_encode')).toLowerCase();
        if (this.encode == "false") {
            this.encode = false;
        }
    }
    if (!IsEmpty(Request('phprpc_callback'))) {
        this.callback = utf8to16(base64decode(String(Request('phprpc_callback'))));
    }
    else {
        this.callback = "";
    }
    this.ref = true;
    if (!IsEmpty(Request('phprpc_ref'))) {
        this.ref = String(Request('phprpc_ref')).toLowerCase();
        if (this.ref == "false") {
            this.ref = false;
        }
    }
    this.errno = 0;
    this.errstr = "";
   
    try {
        this.encrypt = false;
        if (!IsEmpty(Request('phprpc_encrypt'))) {
            this.encrypt = String(Request('phprpc_encrypt'));
            if (this.encrypt === "true") this.encrypt = true;
            if (this.encrypt === "false") this.encrypt = false;
        }
        if (!IsEmpty(Request('phprpc_func'))) {
            func = String(Request('phprpc_func'));
            if (this.is_defined(func)) {
                if (!IsEmpty(Request('phprpc_args'))) {
                    args = base64decode(String(Request('phprpc_args')));
                    if (this.encrypt > 0) {
                        if (typeof(Session('PHPRPC_ENCRYPT')['k']) != "undefined") {
                            args = xxtea_decrypt(args, Session('PHPRPC_ENCRYPT')['k']);
                        }
                        else {
                            this.errno = 1;
                            this.errstr = "Can't find the key for decryption.";
                        }
                    }
                    args = unserialize(args);
                }
                else {
                    args = [];
                }
                result = serialize(this.call(func, args));
                if (this.ref) {
                    args = serialize(args);
                }
                if (this.encrypt > 0) {
                    if (typeof(Session('PHPRPC_ENCRYPT')['k']) != "undefined") {
                        if (this.encrypt > 1) {
                            result = xxtea_encrypt(result, Session('PHPRPC_ENCRYPT')['k']);
                        }
                        if (this.ref) {
                            args = xxtea_encrypt(args, Session('PHPRPC_ENCRYPT')['k']);
                        }
                    }
                    else {
                        this.errno = 1;
                        this.errstr = "Can't find the key for encryption.";
                    }
                }
                if (this.encode) {
                    result = base64encode(result);
                    if (this.ref) {
                        args = base64encode(args);
                    }
                }
                else {
                    result = addjsslashes(result);
                    if (this.ref) {
                        args = addjsslashes(args);
                    }
                }
            }
            else {
                this.errno = 1;
                this.errstr = "Can't find this function " + func + "().";
            }
            Response.Clear();
            if (this.errno != 1) {
                Response.Write('phprpc_result="' + result + '";\r\n');
                if (this.ref) {
                    Response.Write('phprpc_args="' + args + '";\r\n');
                }
            }
            Response.Write('phprpc_errno="' + this.errno + '";\r\n');
            if (this.encode) {
                Response.Write('phprpc_errstr="' + base64encode(utf16to8(this.errstr)) + '";\r\n');
                Response.Write('phprpc_output="";\r\n');
            }
            else {
                Response.Write('phprpc_errstr="' + addjsslashes(this.errstr, false) + '";\r\n');
                Response.Write('phprpc_output="";\r\n');
            }
        }
        else {
            if (this.encrypt != false) {
                if (this.encrypt === true) {
                    encrypt = phprpc_keypair[Math.floor(Math.random() * phprpc_keypair.length)];
                    Session('PHPRPC_ENCRYPT') = [];
                    Session('PHPRPC_ENCRYPT')['x'] = rand(127, 1);
                    Session('PHPRPC_ENCRYPT')['g'] = dec2num(encrypt['g']);
                    Session('PHPRPC_ENCRYPT')['p'] = dec2num(encrypt['p']);
                    encrypt['y'] = num2dec(pow_mod(Session('PHPRPC_ENCRYPT')['g'],
                                                   Session('PHPRPC_ENCRYPT')['x'],
                                                   Session('PHPRPC_ENCRYPT')['p']));
                }
                else {
                    Session('PHPRPC_ENCRYPT')['y'] = dec2num(this.encrypt);
                    var key = num2str(pow_mod(Session('PHPRPC_ENCRYPT')['y'],
                                              Session('PHPRPC_ENCRYPT')['x'],
                                              Session('PHPRPC_ENCRYPT')['p']));
                    var n = 16 - key.length;
                    var k = [];
                    for (var i = 0; i < n; i++) {
                        k[i] = '\0';
                    }
                    k[n] = key;
                    Session('PHPRPC_ENCRYPT')['k'] = k.join('');
                    encrypt = true;
                }
                if (this.encode) {
                    Response.Write('phprpc_encrypt="' + base64encode(serialize(encrypt)) + '";\r\n');
                }
                else {
                    Response.Write('phprpc_encrypt="' + addjsslashes(serialize(encrypt)) + '";\r\n');
                }
            }
            if (this.encode) {
                Response.Write('phprpc_functions="' + base64encode(serialize(this.functions)) + '";\r\n');
            }
            else {
                Response.Write('phprpc_functions="' + addjsslashes(serialize(this.functions)) + '";\r\n');
            }
        }
        Response.Write(this.callback);
    }
    catch (e) {
        this.errno = 1;
        this.errstr = e.description;
        Response.Clear();
        Response.Write('phprpc_errno=' + this.errno + ';\r\n');
        if (this.encode) {
            Response.Write('phprpc_errstr="' + base64encode(utf16to8(this.errstr)) + '";\r\n');
        }
        else {
            Response.Write('phprpc_errstr="' + addjsslashes(this.errstr, false) + '";\r\n');
        }
        Response.Write('phprpc_output="";\r\n');
        Response.Write(this.callback);
    }
    Response.End();
}
 
phprpc_server.prototype.is_defined = function (func) {
    for (var i = 0, n = this.functions.length; i < n; i++) {
        if (this.functions[i] == func) return true;
    }
    return false;
}
 
phprpc_server.prototype.call = function (func, args) {
    var a = [];
    for (var i = 0, n = args.length; i < n; i++) {
        a[i] = 'args[' + i + ']';
    }
    return eval(func + "(" + a.join(', ') + ")");
}
 
phprpc_server.create = function (functions) {
    new phprpc_server(functions);
}
下面的程序 keypair.js 是自动生成的,生成该程序的程序与生成 keypair.php 的程序差不多,这里就不单独提供了,我会在以后的 phprpc_2.1 包中发布的。

phprpc_client.js
/**
* @author      Ma Bingyao(andot@ujn.edu.cn)
* @copyright   CoolCode.CN
* @package     ASP_PHPRPC_CLIENT
* @version     2.1
* @last_update 2006-06-14
* @link        http://www.coolcode.cn/?p=143
*
* Example usage:
*
* server.asp
* <%@ CodePage = 65001 %>
* <script runat="server" type="text/javascript" src="phprpc_client.js"></script>
* <%
* phprpc_client.create('rpc')
* rpc.use_service('http://test.coolcode.cn/phprpc/server.php')
* Response.Write(rpc.add(1,2))
* %>
*/
 
function phprpc_error(errno, errstr) {
    this.errno = errno;
    this.errstr = errstr;
}
 
function phprpc_client() {
    this.__url = '';
    this.__encrypt = false;
    this.encrypt = 0;
    this.args = null;
    this.warning = null;
    this.output = "";
    this.use_service = function (url, encrypt) {
        if (typeof(encrypt) == "undefined") {
            encrypt = this.__encrypt;
        }
        if (typeof(this.__name) == "undefined") {
            return false;
        }
        this.__url = url;
        var xmlhttp = this.__create_xmlhttp(); 
        if (encrypt === true) {
            xmlhttp.open("GET", [this.__url, '?phprpc_encrypt=true&phprpc_encode=false'].join(''), false);
            xmlhttp.send(null);
            if (xmlhttp.responseText) {
                eval(xmlhttp.responseText);
                if (typeof(phprpc_encrypt) == "undefined") {
                    this.__encrypt = false;
                    encrypt = false;
                }
                else {
                    this.__encrypt = unserialize(phprpc_encrypt);
                    this.__encrypt['p'] = dec2num(this.__encrypt['p']);
                    this.__encrypt['g'] = dec2num(this.__encrypt['g']);
                    this.__encrypt['y'] = dec2num(this.__encrypt['y']);
                    this.__encrypt['x'] = rand(127, 1);
                    var key = pow_mod(this.__encrypt['y'],
                                      this.__encrypt['x'],
                                      this.__encrypt['p']);
                    key = num2str(key);
                    var n = 16 - key.length;
                    var k = [];
                    for (var i = 0; i < n; i++) k[i] = '\0';
                    k[n] = key;
                    this.__encrypt['k'] = k.join('');
                    encrypt = num2dec(pow_mod(this.__encrypt['g'],
                                              this.__encrypt['x'],
                                              this.__encrypt['p']));
                }
            }
        }
 
        xmlhttp.open("GET", [this.__url, '?phprpc_encrypt=', encrypt, '&phprpc_encode=false'].join(''), false);
        xmlhttp.send(null);
        if (xmlhttp.responseText) {
            eval(xmlhttp.responseText);
            var functions = unserialize(phprpc_functions);
            var func = [];
            for (var i = 0, n = functions.length; i < n; i++) {
                func[i] = [this.__name, ".", functions[i],
                        " = function () { return this.__call('",
                        functions[i],
                        "', this.__args_to_array(arguments)); }\r\n",
                        this.__name, ".", functions[i],
                        ".ref = false;\r\n"].join('');
            }
            eval(func.join(''));
        }
        delete(xmlhttp);
    };
    this.__call = function (func, args) {
        var __args = serialize(args);
        if ((this.__encrypt !== false) && (this.encrypt > 0)) {
            __args = xxtea_encrypt(__args, this.__encrypt['k']);
        }
        __args = base64encode(__args);
        var request = ['phprpc_func=', func,
                       '&phprpc_args=', __args,
                       '&phprpc_encode=false',
                       '&phprpc_encrypt=', this.encrypt];
        var ref = eval([this.__name, ".", func, ".ref"].join(''));
        if (!ref) {
            request[request.length] = '&phprpc_ref=false';
        }
        var xmlhttp = this.__create_xmlhttp();
        var session = {'args': args, 'ref': ref, 'encrypt': this.encrypt};
        xmlhttp.open("POST", this.__url, false);
        xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
        xmlhttp.send(request.join('').replace(/\+/g, '%2B'));
        if (xmlhttp.responseText) {
            this.__get_result(xmlhttp, session);
            this.output = phprpc_output;
            this.args = phprpc_args;
            this.warning = phprpc_warning;
        }
        else {
            phprpc_result = new phprpc_error(1, "No data received from server");
        }
        delete(xmlhttp);
 
        return phprpc_result;
    };
    this.__get_result = function (xmlhttp, session) {
        eval(xmlhttp.responseText);
        phprpc_warning = null;
        if ((phprpc_errno != 1) && (phprpc_errno != 16) &&
            (phprpc_errno != 64) && (phprpc_errno != 256)) {
            if ((this.__encrypt !== false) && (session.encrypt > 0)) {
                if (session.encrypt > 1) {
                    phprpc_result = xxtea_decrypt(phprpc_result, this.__encrypt['k']);
                }
                if (session.ref) {
                    phprpc_args = xxtea_decrypt(phprpc_args, this.__encrypt['k']);
                }
            }
            phprpc_result = unserialize(phprpc_result);
 
            if (session.ref) {
                phprpc_args = unserialize(phprpc_args);
            }
            else {
                phprpc_args = session.args;
            }
            phprpc_warning = new phprpc_error(phprpc_errno, phprpc_errstr);
        }
        else {
            phprpc_result = new phprpc_error(phprpc_errno, phprpc_errstr);
            phprpc_args = session.args;
        }
    }
    this.__create_xmlhttp = function() {
        var MSXML = ['MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];
        var n = MSXML.length;
        for(var i = 0; i < n; i++) {
            try {
                return new ActiveXObject(MSXML[i]);
            }
            catch(e) {}
        }
        throw new Error("Your server does not support xmlhttp objects");
    };
    this.__args_to_array = function (args) {
        var argArray = [];
        var n = args.length;
        for (i = 0; i < n; i++) {
            argArray[i] = args[i];
        }
        return argArray;
    }
}
 
phprpc_client.create = function (name, encrypt) {
    eval([name, ' = new phprpc_client();', name, '.__name = "', name, '";'].join(''));
    if (encrypt) {
        encrypt = true;
        eval([name, '.__encrypt = ', encrypt, ';'].join(''));
    }
}
分享到:
评论

相关推荐

    PHPRPC .Net服务端+客户端

    PHPRPC .Net服务端与客户端是一套跨平台的远程过程调用(RPC)解决方案,专为.NET开发者设计,使得PHP和.NET应用之间能够高效、便捷地进行通信。这套工具集包含了服务端组件和客户端库,允许开发者在PHP环境中调用...

    phprpc客户端文件

    这是一个PHPrpc客户端文件

    jsonrpc:JSONRPC服务器和客户端

    这个“jsonrpc”项目可能是提供了一个用于创建和使用JSONRPC服务器和客户端的PHP库,其名为“jsonrpc-master”。 首先,让我们深入理解JSONRPC协议的核心概念: 1. **请求(Request)**:JSONRPC请求是一个JSON...

    cpp-libjsonrpccpp用于C服务器和客户端的JSONRPC框架

    libjson-rpc-cpp是C++语言实现的一个开源库,专门用于构建JSON-RPC服务器和客户端应用。这个框架为开发人员提供了一种简单、高效的方式来进行跨平台的通信,支持HTTP和TCP/IP协议,同时还提供了异步调用的能力。 ...

    phprpc for java 服务器实例

    Phprpc是一个跨语言的远程过程调用(RPC)框架,它允许PHP和Java应用程序之间进行无缝通信。在本实例中,我们将深入探讨如何在Java环境中设置和使用Phprpc服务器,以便理解其核心概念和操作流程。 1. **Phprpc简介*...

    Python XML RPC服务器端和客户端实例

    一、远程过程调用RPC XML-RPC is a Remote Procedure Call method that uses XML passed via HTTP as a transport. With it, a client can call methods with parameters on a remote server (the server is named ...

    hessian服务器和客户端

    在本项目中,我们探讨的是基于C#实现的Hessian服务端和客户端,已经在IIS环境下进行了测试并成功通过。 1. **Hessian协议**:Hessian是由Caucho公司开发的一种轻量级、高效的二进制协议,主要用于Web服务。它支持...

    PHPRPC asp.net的结合!

    PHPRPC(PHP Remote Procedure Call)是一种轻量级的跨平台、跨语言的远程过程调用协议,主要用于实现PHP和其它编程语言之间的通信,如ASP.NET。在这个场景中,它作为一个桥梁,使得ASP.NET应用能够与PHP应用进行...

    java基于RPC框架的阶乘计算客户端与服务端

    RPC框架在这里的作用就是使得客户端和服务器之间的通信变得简单、高效。常见的Java RPC框架有Hessian、Dubbo、gRPC等,它们都提供了自动序列化、网络传输、服务发现等核心功能。 项目结构可能包括以下部分: 1. **...

    mongoose 小型 嵌入式 http 服务器

    JSON-RPC客户端,服务器 MQTT客户端,服务器 CoAP客户端,服务器 DNS客户端、DNS服务器、异步DNS解析器 源代码基于ISO C和ISO C++标准 集成简单,只有一个.c和.h文件 经过广泛的测试,已经维护了十年,并被NASA、...

    phprpc_3.0_delphi.zip_Free!_PHPRPC delp_PHPRPC for delp_delphi

    联系web和windows 应用的软件PHPRPC. PHPRPC for Delphi 是针对 Delphi 6 - 2009 原生程序开发版本的。如果你想将 PHPRPC 用于 Delphi.NET,请参见 PHPRPC for .NET 章节的相关内容。 PHPRPC for Delphi 的安装 ...

    Python-reflectrpc实现一个RPC客户端和服务器Python库

    通过发送一个特殊的请求,客户端可以获得服务器的接口描述,然后根据这些信息构造合适的RPC调用。这种方式避免了硬编码服务接口,使得客户端代码更加灵活,适应服务器接口的变化。 在压缩包"aheck-reflectrpc-c4883...

    GO语言通过Thrift服务器和客户端通信(经典)

    **GO语言通过Thrift服务器和客户端通信(经典)** 在软件开发中,跨语言通信是一个常见的需求,Thrift就是一种高效、轻量级的跨语言服务框架,它由Facebook开发并开源,支持多种编程语言,包括Go语言。本文将详细...

    php rpc远程过程调用

    - **跨平台**:只要是PHP环境,就可以实现PHPRPC的客户端和服务端。 - **安全**:通过加密和身份验证机制,PHPRPC可以确保通信的安全性。 - **支持多种序列化方式**:包括PHP序列化、JSON、XML等多种数据交换格式...

    JSON-RPC.rar+服务客户端通信+微服务架构应用

    JSON-RPC客户端开发 JSON-RPC服务器端开发 JSON-RPC安全性考虑 JSON-RPC跨域资源共享CORS JSON-RPC与WebSocket结合使用 JSON-RPC在微服务架构中的角色 JSON-RPC高级特性:通知与订阅 JSON-RPC实战:构建分布式应用

    Linux:rpc客户端服务端通信

    linux rpc实现客户端、服务端通信,开两个终端窗口分别使用指令./test_server 和./test_client 127.0.0.1 即可

    hessian 服务器 客户端 demo

    综上所述,"hessian 服务器 客户端 demo"是一个演示如何使用Hessian协议实现服务器和客户端之间的RPC通信的示例。这个压缩包可能包含了服务器和客户端的代码实现,帮助开发者了解和学习如何在实际项目中应用Hessian...

    基于protobuf和gRPC的消息订阅服务器和客户端.zip

    在本项目"基于protobuf和gRPC的消息订阅服务器和客户端"中,我们将探讨如何使用Python来实现一个这样的系统,它允许客户端订阅并接收来自服务器的消息。 protobuf(Protocol Buffers)是一种数据序列化协议,它可以...

    JsonRPC, 简单的Json RPC PHP客户机/服务器只.zip

    JsonRPC, 简单的Json RPC PHP客户机/服务器只 JsonRPC PHP客户端和服务器一个简单的json rpc客户机/服务器。 特性仅限 json rpc 2.0服务器支持批处理请求和通知基于身份验证和IP的客户端限制自定义中间件完全单元...

    phprpc中文文档

    同时,文档会指导如何设置服务器环境,确保PHP版本兼容,以及如何配置服务端和客户端的连接参数。 4. **服务定义与调用** 在Phprpc中,服务是由一系列可被远程调用的方法组成的。开发者可以通过定义类和方法来创建...

Global site tag (gtag.js) - Google Analytics