Version 6 of JSON-RPC

Updated 2012-01-27 19:10:20 by MaxJarek

JSON-RPC is a stateless, light-weight remote procedure call (RPC) protocol. It uses JSON (RFC 4627) as data format, and is transport-independent. It is designed to be simple! - from the JSON-RPC specification [L1 ].

APN 20080705 A Tcl implementation of the JSON-RPC client-side API is now part of TclSOAP. Most of the server-side calls are implemented, but not integrated with any http servers.

MaxJarek JSON-RPC is my primary technology for client-server applications. I use Tk GUI on client side and Wibble as JSON-RPC http server. Sample client example:

package require JSONRPC
JSONRPC::create add -proxy "http://www.raboof.com/projects/jayrock/demo.ashx" \
        -params { val1 int val2 int }

puts [::add 2 3456]

Sample server side example (for wibble::jsonrpc::proxy package):

namespace eval ::wibble::json-rpc {
  proc add {a b} {return [expr {$a+$b}]}
}

TclSOAP don't support https transport for JSON-RPC. I have created patch for SOAP::https which is waiting in repo.

wibble::jsonrpc::proxy is my package thats change Wibble in good (for me) SOA application server. jsonrpc-proxy needs same corrects in Wibble core. I am waiting for new Wibble version then proxy package will be public available. :)

AMG: Please let me know what changes you would like in the Wibble core, and I'll see what I can incorporate directly. For anything that I can't just drop in without breaking compatibility and/or adding prerequisites, I may have ideas on how to modify the core to be more receptive to outside customization.

The next version of Wibble, when I have time to work on it, should feature charset support, rather than being tied to ISO8859-1. That's my primary goal. I'm also collecting little fixes and updates. For example, I modified [getrequest] to permit application/json-rpc to be parsed by a zone handler, and I modified [listen] to work better with TLS, both thanks to your suggestions and contributions.

MaxJarek: Ok, let's start with Wibble 0.2 :). This is initial version.

# Simple JSONRPC proxy for Wibble
# J. Lewandowski, (MaxJarek)
# Available under the Tcl/Tk license.  http://tcl.tk/software/tcltk/license.html

package provide wibble::jsonrpc::proxy 0.1

namespace eval ::wibble::zone {

proc jsonrpc-proxy {namespace state} {

  dict set state response status 200
  dict set state response header content-type "" "application/json-rpc; charset=utf-8"

  dict with state request {}
  if {$method eq "POST" && [dict exists $header content-type ""] && [dict get $header content-type ""] eq "application/json-rpc"} {

    array set json_req [json::json2dict [dehex $rawpost]]

    # execute method with params
    catch {set result [eval ${namespace}::$json_req(method) $json_req(params)]} err

  } else {

    set err "JSON-RPC error"

  }

  if {![info exists result]} {
        dict set state response content [json::write object id null \
                error [json::write object name [json::write string JSONRPCError] message [json::write string $err]]]
        ::wibble::log "JSON-RPC: $err"
  } else {
        dict set state response content [json::write object result [json::write string $result] id $json_req(id)]
  }

  sendresponse [dict get $state response]

}

}

Example Wibble startup script:

namespace eval ::wibble::json-rpc {
  proc strlen {a} {return "[string length $a]"}
  proc date {} {return [clock seconds]}
  proc add {a b} {return [expr {$a+$b}]}
}

package require wibble
package require json
package require json::write
package require wibble::jsonrpc::proxy

set ::wibble::zonehandlers {}
::wibble::handle /maxgui [list jsonrpc-proxy ::wibble::json-rpc]
::wibble::handle / notfound

wibble::listen 8080
vwait forever

Example client code:

package require JSONRPC
JSONRPC::configure -transport http
JSONRPC::create add -proxy "http://localhost:8080/maxgui" \
        -params { val1 int val2 int }
puts [::add 2 3456]

If you want any new json-rpc method simple insert new funkcion in ::wibble::json-rpc namespace