提交 bdf0a4b5 编写于 作者: S Steven Barth

GSoC: Add RPC client

上级 c47be2e7
include ../../build/config.mk
include ../../build/module.mk
\ No newline at end of file
--[[
LuCIRPCc
(c) 2009 Steven Barth <steven@midlink.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local util = require "luci.util"
local json = require "luci.json"
local ltn12 = require "luci.ltn12"
local nixio = require "nixio", require "nixio.util"
local tostring, assert, setmetatable = tostring, assert, setmetatable
local error = error
--- LuCI RPC Client.
-- @cstyle instance
module "luci.rpcc"
RQLIMIT = 32 * nixio.const.buffersize
--- Create a new JSON-RPC stream client.
-- @class function
-- @param fd File descriptor
-- @param v1 Use protocol version 1.0
-- @return RPC Client
Client = util.class()
function Client.__init__(self, fd, v1)
self.fd = fd
self.uniqueid = tostring(self):match("0x([a-f0-9]+)")
self.msgid = 1
self.v1 = v1
end
--- Request an RP call and get the response.
-- @param method Remote method
-- @param params Parameters
-- @param notification Notification only?
-- @return response
function Client.request(self, method, params, notification)
local oldchunk = self.decoder and self.decoder.chunk
self.decoder = json.ActiveDecoder(self.fd:blocksource(nil, RQLIMIT))
self.decoder.chunk = oldchunk
local reqid = self.msgid .. self.uniqueid
local reqdata = json.Encoder({
id = (not notification) and (self.msgid .. self.uniqueid) or nil,
jsonrpc = (not self.v1) and "2.0" or nil,
method = method,
params = params
})
ltn12.pump.all(reqdata:source(), self.fd:sink())
if not notification then
self.msgid = self.msgid + 1
local response = self.decoder:get()
assert(response.id == reqid, "Invalid response id")
if response.error then
error(response.error.message or response.error)
end
return response.result
end
end
--- Create a transparent RPC proxy.
-- @param prefix Method prefix
-- @return RPC Proxy object
function Client.proxy(self, prefix)
prefix = prefix or ""
return setmetatable({}, {
__call = function(proxy, ...)
return self:request(prefix, {...})
end,
__index = function(proxy, name)
return self:proxy(prefix .. name .. ".")
end
})
end
\ No newline at end of file
--[[
LuCIRPCc
(c) 2009 Steven Barth <steven@midlink.org>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
$Id$
]]--
local util = require "luci.util"
local rawget, setmetatable = rawget, setmetatable
local ipairs = ipairs
--- Transparent UCI over RPC client.
-- @cstyle instance
module "luci.rpcc.ruci"
local Proxy = util.class()
--- Create a new UCI over RPC proxy.
-- @param rpccl RPC client
-- @return Network transparent UCI module
function factory(rpccl)
return {
cursor = function(...)
return Proxy(rpccl, rpccl:request("ruci.cursor", {...}))
end,
cursor_state = function(...)
return Proxy(rpccl, rpccl:request("ruci.cursor_state", {...}))
end
}
end
function Proxy.__init__(self, rpccl, objid)
self.__rpccl = rpccl
self.__objid = objid
setmetatable(self, {
__index = function(self, key)
return rawget(self, key) or Proxy[key] or function(self, ...)
local argv = {self.__objid, ...}
return self.__rpccl:request("ruci."..key, argv)
end
end
})
end
function Proxy.foreach(self, config, section, callback)
local sections = self.__rpccl:request("ruci.foreach", {self.__objid, config, section})
if sections then
for _, s in ipairs(sections) do
callback(s)
end
return true
else
return false
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册