You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

358 lines
12 KiB

/*
jsonrpc-2.0 over http
mode:async
exp:
by:liangliangit
v2.0 beta
2.0 beta功能
新增send方法 建议用send方法替代call方法
新增错误码订阅事件委托 例如可以订阅一份账户未登录的错误通知信息,然后处理用户跳转到登录页面,而不需要每次都判断请求是否未授权
新增日志打印开启,关闭功能,默认开启
*/
const jsonrpc={
//会话
_session:{
key:localStorage.getItem("jsonrpc_session_key")
},
//错误信息订阅通知 (例如可以订阅一份账户未登录的错误通知信息,然后处理用户跳转到登录页面)
errnotifys:new Map(),
//返回订阅id便于取消订阅
errNotifyAdd:function(errcode,callback){
let callfuncs = this.errnotifys.get(errcode)
if (callfuncs == null || callfuncs == undefined || callfuncs == ""){
let funcs = []
funcs.push(callback)
this.errnotifys.set(errcode,funcs)
return 0
}
let index = callfuncs.length
callfuncs[index]=callback
this.errnotifys.set(errcode,callfuncs)
return index
},
errNotifyDel:function(errcode,id){
let callfuncs = this.errnotifys.get(errcode)
if (callfuncs == null || callfuncs == undefined || callfuncs == ""){
return
}
callfuncs.delete(id)
this.errnotifys.set(errcode,callfuncs)
},
_errNotify:function(errcode){
let callfuncs = this.errnotifys.get(errcode)
if (callfuncs == null || callfuncs == undefined || callfuncs == ""){
return
}
for(let func in callfuncs){
callfuncs[func]()
}
},
strict:true,
log:false,
jsonRequestCode:{
jsonrpc:"2.0",
method:"",
params:{},
id:"",
timestampin:"",
},
jsonResponseCode:{
jsonrpc:"2.0",
result:{},
id:"",
timestampin:"",
timestampout:"",
error:{
message:"",
code:"",
data:""
},
},
setSessionKey:function(key){
localStorage.setItem("jsonrpc_session_key",key)
this._session.key = key
},
setUrl:function(url){
localStorage.setItem("jsonrpc_url",url)
},
send:function(url,rpcRequest,callback,errorcall){
let guid = this.guid()
rpcRequest.id=guid
rpcRequest.jsonrpc = "2.0"
rpcRequest.session = this._session.key
let now = new Date().getTime()
rpcRequest.timestampin=now.toString()
let jsonString = JSON.stringify(rpcRequest)
if (this.log){console.log("rpcCall to service:"+url);console.log(jsonString)}
let jsonrpc = this
this.asyncpost(url,jsonString).then(
rpcResponse=>{
if (jsonrpc.log){console.log(rpcResponse)}
if(!rpcResponse){
this._onError("收到了错误的响应:无法解析json字符串")
if (typeof (errorcall) == "function"){
let error={
message:"收到了错误的响应:无法解析json字符串",
code:-1,
data:{}
}
errorcall(error)
}
return
}
if(this.strict){
if(rpcResponse.id == "" || rpcResponse.id == undefined){
this._onError("收到了错误的响应:无法解析response.id,id为必须参数")
if (typeof (errorcall) == "function"){
let error={
message:"收到了错误的响应:无法解析response.id,id为必须参数",
code:-1,
data:{}
}
errorcall(error)
}
return
}
if(rpcResponse.jsonrpc != "2.0"){
this._onError("收到了错误的响应:无法解析JSON-RPC,jsonrpc参数必须为2.0")
if (typeof (errorcall) == "function"){
let error={
message:"收到了错误的响应:无法解析JSON-RPC,jsonrpc参数必须为2.0",
code:-1,
data:{}
}
errorcall(error)
}
return
}
if(rpcResponse.error.code != 200){
//this._onError(rpcResponse.error)
if (typeof (errorcall) == "function"){
errorcall(rpcResponse.error)
}
jsonrpc._errNotify(rpcResponse.error.code)
return
}
}
callback(rpcResponse)
}
)
},
//input jsonrpc.request
//return jsonrpc.response.result
result:function(url,rpcRequest){
let guid = this.guid()
rpcRequest.id=guid
rpcRequest.jsonrpc = "2.0"
rpcRequest.session = this._session.key
let now = new Date().getTime()
rpcRequest.timestampin=now.toString()
let jsonString = JSON.stringify(rpcRequest)
if (this.log){console.log("rpcCall to service:"+url);console.log(jsonString)}
let jsonrpc = this
return new Promise(function(resolve, reject) {
jsonrpc.asyncpost(url,jsonString).then(
rpcResponse=>{
if (jsonrpc.log){console.log(rpcResponse)}
if(!rpcResponse){
jsonrpc._onError("收到了错误的响应:无法解析json字符串")
let error={
message:"收到了错误的响应:无法解析json字符串",
code:-1,
data:{}
}
reject(error)
return
}
if(jsonrpc.strict){
if(rpcResponse.id == "" || rpcResponse.id == undefined){
jsonrpc._onError("收到了错误的响应:无法解析response.id,id为必须参数")
let error={
message:"收到了错误的响应:无法解析response.id,id为必须参数",
code:-1,
data:{}
}
reject(error)
return
}
if(rpcResponse.jsonrpc != "2.0"){
jsonrpc._onError("收到了错误的响应:无法解析JSON-RPC,jsonrpc参数必须为2.0")
let error={
message:"收到了错误的响应:无法解析JSON-RPC,jsonrpc参数必须为2.0",
code:-1,
data:{}
}
reject(error)
return
}
if(rpcResponse.error.code != 200){
jsonrpc._errNotify(rpcResponse.error.code)
reject(rpcResponse.error)
return
}
}
resolve(rpcResponse.result)
}
)
})
},
fetch:function(url,rpcRequest){
let guid = this.guid()
rpcRequest.id=guid
rpcRequest.jsonrpc = "2.0"
rpcRequest.session = this._session.key
let now = new Date().getTime()
rpcRequest.timestampin=now.toString()
let jsonString = JSON.stringify(rpcRequest)
if (this.log){console.log("rpcCall to service:"+url);console.log(jsonString)}
let jsonrpc = this
return new Promise(function(resolve, reject) {
jsonrpc.asyncpost(url,jsonString).then(
rpcResponse=>{
if (jsonrpc.log){console.log(rpcResponse)}
if(!rpcResponse){
jsonrpc._onError("收到了错误的响应:无法解析json字符串")
let error={
message:"收到了错误的响应:无法解析json字符串",
code:-1,
data:{}
}
reject(error)
return
}
if(jsonrpc.strict){
if(rpcResponse.id == "" || rpcResponse.id == undefined){
jsonrpc._onError("收到了错误的响应:无法解析response.id,id为必须参数")
let error={
message:"收到了错误的响应:无法解析response.id,id为必须参数",
code:-1,
data:{}
}
reject(error)
return
}
if(rpcResponse.jsonrpc != "2.0"){
jsonrpc._onError("收到了错误的响应:无法解析JSON-RPC,jsonrpc参数必须为2.0")
let error={
message:"收到了错误的响应:无法解析JSON-RPC,jsonrpc参数必须为2.0",
code:-1,
data:{}
}
reject(error)
return
}
if(rpcResponse.error.code != 200){
jsonrpc._errNotify(rpcResponse.error.code)
reject(rpcResponse.error)
return
}
}
resolve(rpcResponse.result)
}
)
})
},
//生成guid
guid:function() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
let r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8)
return v.toString(16)
})
},
_onHttpError:function(err){
this.onHttpError(err)
},
onHttpError:function(err){},
_onError:function(err){
this.onError(err)
},
onError:function(err){},
asyncpost:function(url,jsonString){
let r = fetch(url,
{
method: 'POST', // or 'PUT'
mode: 'cors',
headers: {
'Content-Type': 'application/json',
},
body: jsonString
}
).then(response => {
if(response.status != 200){
this._onHttpError(response.error)
let rpcResponse={
jsonrpc:"2.0",
id:"1",
error:{
message:"http响应错误:"+response.status,
code:-1
}
}
return rpcResponse
}
return response.json()
}).catch(response => {
this._onHttpError(response)
let rpcResponse={
jsonrpc:"2.0",
id:"1",
error:{
message:"网路连接失败,请重试",
code:-1
}
}
return rpcResponse
})
return r
},
}
export default jsonrpc