Changeset 38

Show
Ignore:
Timestamp:
01/22/06 18:20:25 (3 years ago)
Author:
Jan-Klaas Kollhof
Message:

experimental rpc code

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/jsolait/lib/jsonrpc.js

    r35 r38  
    211211            } 
    212212        }; 
    213          
    214213        /** 
    215214            Sets username and password for HTTP Authentication. 
     
    251250    mod.ServiceProxy=Class(function(publ){ 
    252251        /** 
    253             Initializes a new ServerProxy. 
     252            Initializes a new ServiceProxy. 
    254253            The arguments are interpreted as shown in the examples: 
    255             ServerProxy("url", ["methodName1",...]) 
    256             ServerProxy("url", ["methodName1",...], "user", "pass") 
    257             ServerProxy("url", "user", "pass") 
     254            ServiceProxy("url", ["methodName1",...]) 
     255            ServiceProxy("url", ["methodName1",...], "user", "pass") 
     256            ServiceProxy("url", "user", "pass") 
    258257 
    259258            @param url                     The url of the service. 
     
    320319    }); 
    321320 
    322     ///@deprecated  Use ServiceProxy instead. 
    323     mod.ServerProxy= mod.ServiceProxy; 
    324      
    325      
    326    
     321     
     322 
     323    mod.NotificationReceiver = Class(function(publ,supr){ 
     324         publ.__init__ = function(url){ 
     325            this._url = url; 
     326            var req = new XMLHttpRequest() 
     327            req.multipart = true; 
     328            var self = this; 
     329            req.open('POST', url, true) 
     330            req.onload = function(evt){ 
     331                self._handleData(evt.target.responseText); 
     332            } 
     333            req.send(''); 
     334        }; 
     335         
     336         
     337        publ._handleData = function(data){ 
     338            var f = new Function('','return ' + data); 
     339            var o = f(); 
     340            if(this[o.method]){ 
     341                this[o.method].apply(this, o.params); 
     342            } 
     343         }; 
     344    }); 
     345     
     346     
     347    mod.HTTPConnection=Class(function(publ,supr){ 
     348        publ.__init__=function(url, datahandler){ 
     349            this.url = url; 
     350            this.datahandler = datahandler; 
     351        }; 
     352         
     353        publ.send = function(data){ 
     354            var datahandler = this.datahandler; 
     355            urllib.postURL(this.url, data, function(req){ 
     356                datahandler(req.responseText); 
     357            }); 
     358        } 
     359    }); 
     360     
     361    mod.ContinousHTTPConnection=Class(function(publ,supr){ 
     362         
     363         publ.__init__=function(url, datahandler){ 
     364            this.url = url; 
     365            this.datahandler = datahandler; 
     366            this.queue=[]; 
     367            this.isWaitingForResponse=false; 
     368            this.isWaitingForServer=false; 
     369            this.processQueue(); 
     370        }; 
     371         
     372        publ.send = function(data){ 
     373            this.queue.push(data); 
     374            this.processQueue(); 
     375        }; 
     376         
     377        publ.waitForServer=function(){ 
     378            this.isWaitingForServer=true; 
     379            var self=this; 
     380            this.currentRequest= urllib.postURL(this.url, "", function(req){ 
     381                self.isWaitingForServer=false; 
     382                self.processData(req.responseText); 
     383            }); 
     384        }; 
     385         
     386        publ.processData = function(data){ 
     387            if(data!=''){ 
     388                this.datahandler(data); 
     389            } 
     390            this.processQueue(); 
     391        }; 
     392                 
     393        publ.sendAndWaitResponse=function(data){ 
     394            this.isWaitingForResponse=true; 
     395            var self = this; 
     396            this.currReq = urllib.postURL(this.url, data, function(req){ 
     397                self.isWaitingForResponse = false; 
     398                self.processData(req.responseText); 
     399            }); 
     400        }; 
     401         
     402        publ.processQueue = function(){ 
     403            if((this.queue.length > 0) && (! this.isWaitingForResponse)){ 
     404                var data =this.queue.join(""); 
     405                this.queue=[]; 
     406                this.sendAndWaitResponse(data);             
     407            } 
     408             
     409            if((! this.isWaitingForServer) && (! this.isWaitingForResponse)){ 
     410                this.waitForServer(); 
     411            } 
     412        }; 
     413    }); 
     414     
     415     
     416    mod.RPCMethod=Class(function(publ,supr){ 
     417        publ.__init__=function(name,proxy){ 
     418            this.name = name; 
     419            this.proxy = proxy; 
     420        }; 
     421         
     422        publ.__call__=function(){ 
     423            var args=new Array(); 
     424            for(var i=0;i<arguments.length;i++){ 
     425                args.push(arguments[i]); 
     426            } 
     427            if(typeof args[args.length-1] == "function"){ 
     428                var callback = args.pop(); 
     429                return this.proxy._sendRequest(this.name, args, callback); 
     430            }else{ 
     431                return this.proxy._sendNotification(this.name, args); 
     432            }; 
     433        }; 
     434    }) 
     435     
     436    mod.ServiceProxy2=Class(function(publ,supr){ 
     437        publ.__init__ = function(serviceurl, methodNames, localService){ 
     438            this._url = serviceurl;             
     439            var c = new mod.ContinousHTTPConnection(this._url, bind(this, this._handleData)); 
     440            this._attachMethods(methodNames); 
     441            this._localService = localService == null ? {}:localService; 
     442            this._pendingRequests={}; 
     443        }; 
     444         
     445         
     446        /** 
     447            Adds new JSONRPCMethods to the proxy server which can then be invoked. 
     448            @param methodNames   Array of names of methods that can be called on the server. 
     449        */ 
     450        publ._attachMethods = function(methodNames){ 
     451            for(var i=0;i<methodNames.length;i++){ 
     452                var obj = this; 
     453                //setup obj.childobj...method 
     454                var names = methodNames[i].split("."); 
     455                for(var n=0;n<names.length-1;n++){ 
     456                    var name = names[n]; 
     457                    if(obj[name]){ 
     458                        obj = obj[name]; 
     459                    }else{ 
     460                        obj[name]  = new Object(); 
     461                        obj = obj[name]; 
     462                    } 
     463                } 
     464                var name = names[names.length-1]; 
     465                if(obj[name]){ 
     466                }else{ 
     467                    var mth = new mod.RPCMethod(methodNames[i], this); 
     468                    obj[name] = mth; 
     469                } 
     470            } 
     471        }; 
     472         
     473        publ._handleData = function(data){ 
     474            var d = 'return [' + data.replace(/\n/g, ",") + ']'; 
     475            try{ 
     476                f=new Function('',d); 
     477                var messages = f(); 
     478            }catch(e){ 
     479                throw new mod.MalformedJSONRpc("The JSON-RPC data is not parsable",  data, e); 
     480            } 
     481             
     482            for(var i=0;i<messages.length;i++){ 
     483                if(messages[i].method != null  && messages[i].params != null && messages[i].id !=null){ 
     484                    this._handleInvokation(messages[i].method, messages[i].params, messages[i].id); 
     485                }else if(messages[i].method != null  && messages[i].params != null && messages[i].id == null){ 
     486                    this._handleNotification(messages[i].result, messages[i].error); 
     487                }else if(messages[i].id != null){ 
     488                    this._handleResponse(messages[i].result, messages[i].error, messages[i].id); 
     489                }else{ 
     490                    throw new mod.MalformedJSONRpc("The JSON-RPC message does not contain appropriate properties", d); 
     491                } 
     492            } 
     493        }; 
     494         
     495        publ._handleResponse=function(result, err, id){ 
     496            var r = this._pendingRequests[id]; 
     497            if(r){ 
     498                delete this._pendingRequests[id]; 
     499                r.handleResponse(result, err); 
     500            } 
     501        }; 
     502         
     503        publ._handleInvokation=function(method, params, id){ 
     504            if(this._localService[method]){ 
     505                var rslt = this._localService[method].apply(this._localService, params); 
     506                if(isinstanceof(rslt, mod.DelayedResponse)){ 
     507                    rslt.id=id; 
     508                }else{ 
     509                    this._sendResponse(rslt, null, id); 
     510                } 
     511            }else{ 
     512                this._sendResponse(null, "Method Not Found", id); 
     513            }; 
     514        }; 
     515         
     516        publ._handleNotification=function(method, params){ 
     517             if(this._localService[method]){ 
     518                this._localService[method].apply(this._localService, params); 
     519            } 
     520        }; 
     521         
     522        publ._sendData = function(data){ 
     523            print(data) 
     524        }; 
     525         
     526        publ._sendRequest=function(method, params, callback){ 
     527            var r = new PendingRequest(callback); 
     528            this._pendingRequests[hash(r)] = r; 
     529            var data = mod.marshall({method:method, params:params, id:hash(r)}); 
     530            this._sendData(data); 
     531            return r; 
     532        }; 
     533         
     534        publ._sendNotification=function(method, params){ 
     535            var data = mod.marshall({method:method, params:params, id:null}); 
     536            this._sendData(data); 
     537        }; 
     538         
     539        publ._sendResponse=function(result, error, id){ 
     540            var data = mod.marshall({result:result, error:error, id:id}); 
     541            this._sendData(data); 
     542        }; 
     543         
     544    }); 
     545     
     546    var PendingRequest=Class(function(publ,supr){ 
     547        publ.__init__=function(callback){ 
     548            this.callback=callback; 
     549        }; 
     550         
     551        publ.handleResponse=function(result, error){ 
     552            this.callback.call(null, result, error); 
     553        }; 
     554    }); 
     555     
    327556     
    328557     
     
    383612 
    384613    mod.__main__ = function(){ 
     614        
     615    
    385616        print("creating ServiceProxy object using introspection for method construction...\n"); 
    386617        var s = new mod.ServiceProxy("http://jsolait.net/testj.py",["echo"]);