Netherworld's Pretend Minibar
    Share your code. npm Orgs help your team discover, share, and reuse code. Create a free org »

    msg-rpcpublic

    msg-rpc

    Bidirectional Rpc(Remote procedure call) support over simple message interface, such as WebSocket.

    Now there are WebSocket examples based on socket.io and sockjs. Also there is a simple nodejs local example, where sending messages is just passing variables.

    Simpe Message Vs. Rpc

    Features

    • Simple. Just over simple sendMessage/onMessage interface, no other dependencies.

    • Powerful. Not only normal Rpc, but also a special one: Rpc Service, which make the rpc pushable, in other words, the server can also send a request to the client and expect some kind of response.

    Release notes

    How to use?

    Basically, there're two preparatory things to be done, for both server or client:

    1. Tell how to send out a message
    2. Forward the messages came in to the msg-rpc

    Actually there's normally a 3rd for the server, when the client disconnect, the server should do some clean up work.

    Here's a websocket example between browser/nodejs, but just for illustration purposes. Reference these examples for more details.

    Server (NodeJs):
    • Install the node module

        npm install msg-rpc	
      
    • Create a rpc server object, named rpcSvr, and do the preparatory work (tell how to send message, and forward the messages recevied)

        var MsgRpc = require("msg-rpc"), RpcSvrCls = MsgRpc.rpcServer;
      
        var rpcSvr = new RpcSvrCls({
        	//the real message sending function
        	sendMessage : function(msg, socketId, cb) {
        		
        		//socketId should be a string, which is passed in by the message function(below)
      
        		//send the msg
        		//in socket.io, it'll like this:
        		//clients[socketId].send(JSON.stringify(msg));
        
        		//response
        		cb(error, result);
        	}
        });
      
        //forward the message to the rpcSvr
        //in socket.io, it'll like this:
        //clients[socket.id] = socket;
        //socket.on('message', function(data) {
      
        	//var msg = JSON.parse(data);
      
        	//pass the message to the rpcSvr, with the socketId
        	if (rpcSvr.isRpcMsg(msg))
        		rpcSvr.message(msg, socket.id);
        //});
      
        //cleanup when disconnect
        //socket.on('disconnect', function() {
      
        	rpcSvr.clearupSocketId(socket.id);
      
        	delete clients[socket.id];
        //});
      
    • Then register some procedures to listen for rpc requests.

        //Register a normal procedure named procedureA
        rpcSvr.regRpc('procedureA', function(socketId, args, callback) {
        
        	//response to the request
        	callback(error, result);
        });
      
    Browser:
    • Load the lib, create a rpc client, named rpcClient, and do the preparatory work (tell how to send message, and forward the messages recevied)

        <script src="/build/rpc_client.js"></script>
      
        //create a rpc client, tell how to send the message out
        var rpcClient = new MsgRpc.Client({
        
        	//the real message sending function
        	sendMessage : function(msg) {
        		
        		//in socket.io, it'll like this:
        		//socket.send(JSON.stringify(msg));
        	}
        });
      
        //forward the messages received to the rpcClient
        //in socket.io, it'll like this:
        //socket.on('message', function(data) {
        
        	//var msg = JSON.parse(data);
        
        	//here, pass the msg to the rpcClient
        	if (rpcClient.isRpcMsg(msg))
        		rpcClient.message(msg);
        //});
      
    • Then use the rpcClient to do the work.

        rpcClient.rpc('procedureA', {
        	a : 1
        }, function(err, result) {
      
        	//here's the procedure response
        	console.log('procedureA return ', arguments);
        });
      

    Again, there are socket.io/sockjs/node examples, reference them for more details.

    Advanced usage

    Rpc Service

    Rpc itself is very like http request, client request, server response. But the simple message interface here, e.g. WebSocket, is bidirectional, server can push messages. On the client side, there must be some way to recevie these messages, and the most important, forward them to the right function to deal with.

    That's why another kind of Rpc came out, named as Rpc Service, here's what it's like:

    //Register a service named serviceB
    rpcSvr.regService('serviceB', function(socketId, args, callback, messenger) {
    
    	//compared to regRpc, here we got an extra "messenger" parameter
    });
    

    The key point is the 3rd parameter messenger.

    What's messenger?

    Messenger works as a pair, normally one on the client side, one on the server side. Both work the same way(share the same source code).

    Let's say there is such a pair, MsgerA and MsgerB. It's very like that there's a private pipeline between them, so they can communicate with each other without any other conserns. MsgerA send a message, MsgerB will get that, and vice versa.

    A messenger, e.g. MsgerA got 2 group of functions:

    sendMsg / onMsg
    • Send a message to MsgerB:

        MsgerA.sendMsg(msg); 
      
    • Receive messages from MsgerB

        MsgerA.onMsg(function(msg){
        	//messages from MsgerB
        });
      
    callCmd / onCmd (cmd is very like rpc, just to distinguish)
    • Call cmd which will be excuted on MsgerB

        MsgerA.callCmd('cmdA', args, function(err, result) {
        	//here we got the response from MsgerB
        });
      
    • Listen for cmd requests from MsgerB

        MsgerA.onCmd(function(cmd, args, callbak) {
      
        	//do something, and response to MsgerB
        	callbak(error, result);
        });
      

    With this pair of messengers, bidirectional message/cmd(rpc) communication is supported.

    How the client got the messenger?

    Well, it's up to the Server, client still use the rpc method, but if the procedure is registered by "regService" on the server, then it's a Service procedure, and messenger will be passed in as the 3rd parameter.

    On the server side, rpcSvr.regService('serviceB', function(socketId, args, callback, msgerSvr)...., then, on the client side:

    rpcClient.rpc('serviceB', args, function(err, result, msgerClient) {
    	//here you got the messenger "msgerClient", and with msgerSvr as a pair.
    	//just say hello to the msgerSvr
    	msgerClient.sendMsg({
    		hi : 'hello'
    	});
    }
    

    How could messengers be helpful?

    Messenger is just a variable with msg/cmd interface, when some client call this Rpc Service, the server and client could both keep the messenger variables, and talk to each other in the future.

    Imagine that there's a group chat app, the client could rpc a service to join some group, and the server will keep every client's messenger. When some client send out a message through its messenger, the corresponding messenger on the server side will received that, and the server could just loop through all other messengers in this group and call the sendMsg function. Very easy, right?

    How to build

    msg-rpc use Grunt to build the source under src folder.

    In the project folder, run:

    npm install
    
    grunt
    

    If grunt not installed yet, run:

    npm install -g grunt-cli
    
    grunt
    

    The some final libraries will be generated in the build folder, e.g.

    • rpc_client.js, works on browser

    • rpc_node.js, works on Node

    Keywords

    none

    install

    npm i msg-rpc

    Downloadsweekly downloads

    12

    version

    0.1.5

    license

    none

    repository

    githubgithub

    last publish

    collaborators

    • avatar