npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

nodermi

v0.0.4

Published

RMI(Remote Method Invocation) framework for node.js

Downloads

14

Readme

nodermi

A rmi(Remote Method Invocation) service for node.

No messages, just method invocation. Nodermi makes RPC easy: Remote objects have the same methods as the original objects; Parameters passed to a remote method are automatically converted to remote objects on the server side; You can pass (almost) anything to remote methods.

Remote method invocation is by its nature asynchronous. If you want do something after the remote invocation finishes, use a callback function.

API

Initialize

option{host, port}; callback(error, rmiService)

var nodermi = require('nodermi');
nodermi.createRmiService(option, callback);

rmi service object : register object

name : name for this object, client use this name to lookup remote object. Register entry point to the service you want to expose.

registerObject(name, object)

rmi service object : retrieve remote object by name

option : {host, port, [objName]}. callback(error, stubObject)

retrieveObj(option, callback)

rmi register class

name : a unique name for the class. class : the class constructor

You need register class in all the processes, and the objects of the class needs to implement toConstructorArguments method to dump the object as constructor arguments.

registerClass(name, clazz)

Features

Plain Javascript

You do not to inherit from some special class to make your objects work remotely. No IDL is needed, everything is dynamically generated.

Automatic Remote Objects

The objects(except for pass by value or pass by implementation objects) you pass as arguments for remote method calls are automatically remote objects seen from the server side. No explicitly registration is needed.

There is no centralized point, a process could get remote objects from any other process, a process could pass around its local objects or remote references to any other process.

Pass by value

Simple objects like date, error or none cyclic shallow objects that do not have methods are passed by value in remote method invocations.

Pass by implementation

You can use registerClass API to register classes of objects that need to be passed by implementation. These objects also need to implement a toConstructorArguments method to dump their states as constructor arguments.

Smart Reference

A remote method call will be directly forwarded to the original server where the remote object lives, even the remote object is obtained from some other server. When a "remote" reference is pointing to a local object, the local object is directly used.

Garbage Collection

The remote objects that has no remote or local reference will be garbage collected.

Support Cyclic Objects

Serialization Control

You can control what to send over network by nodermi by add '__r_include', '__r_skip' fields to your objects. By default, properties and methods with '_' prefixed name are omitted. Set '__r_mode' to 'methods' to serialize only methods in that object.

Protocol

We use protobuf to encode our internal messages, the protocol definition is here message.proto. We use dcodeIO's protobuf implementationn.

Sample

var nodermi = require('nodermi');

var serverConf = {
  host: 'localhost',
  port: 7000
};

var clientConf = {
  host: 'localhost',
  port: 8000
};

var serverObj = {
  print: function(str) {
    console.log("print " + str);
  },
  // return the obj in the arguments by callback
  echo: function(obj, callback) {
    console.log("get object: " + obj.name);
    callback(null, obj);
  },
  // this obj could be a remote object!
  invoke: function(obj, callback) {
    console.log("calling doSomething of another object.");
    obj.doSomething(callback);
  }
};

// a cyclic object
var serverObj2 = {
  name: "obj2"
};
serverObj2.ref = serverObj2;


nodermi.createRmiService(serverConf, function(err, server) {
  // register objects with names for clients to lookup
  server.registerObject('serverObj', serverObj);
  server.registerObject('serverObj2', serverObj2);

  // create client rmi instance after the server rmi service is created
  nodermi.createRmiService(clientConf, function(err, client) {
    // create a request to retive remote object
    var retrieveRequest = serverConf;
    retrieveRequest.objName = 'serverObj';
      
    client.retrieveObj(retrieveRequest, function(err, stub) {
      // call serverObj.print
      stub.print("something on client");
      var localObj = {
        name: 'a local object',
        doSomething: function(callback) {
          console.log("i am doing something");
          callback(null);
        }
      };
      stub.echo(localObj, function(err, returned) {
        // the remote function pass back the local object
        console.log("get from server " + (JSON.stringify(returned)));
        // localObj === returned evaluates as true
        console.log("returned is identical to localObj " + (localObj === returned));
      });
      // the local is passed over to the server, and the server will call its doSomething
      stub.invoke(localObj, function(err) {
        console.log("invoke ends");
      });
    });

    var retrieveAllRequest = serverConf;
    retrieveAllRequest.objName = null;
    // this time retrieve all objects
    client.retrieveObj(retrieveAllRequest, function(err, stub) {
       // prints out "obj2", cyclic reference is handled nicely
       console.log(stub.serverObj2.ref.name);
    });
  });
});