#json-rpc #typed #susy #high-level #wrapper #derive #methods

susy-jsonrpc-derive

针对 susy-jsonrpc-core 的高级、类型化包装器

1个稳定版本

10.1.0 2019年3月24日
10.0.2 2019年3月25日

#8#susy

Download history 2/week @ 2024-03-12 2/week @ 2024-03-26 24/week @ 2024-04-02 1/week @ 2024-06-04 91/week @ 2024-06-11

92 每月下载次数
用于 susy-jsonrpc-test

MIT 许可证

32KB
767

针对 susy_jsonrpc_core 的高级、类型化包装器。

允许以类型化的方式创建包含一组RPC方法的“服务”对象。

示例

use susy_jsonrpc_derive::rpc;
use susy_jsonrpc_core::{IoHandler, Error, Result};
use susy_jsonrpc_core::futures::future::{self, FutureResult};

#[rpc]
pub trait Rpc {
	#[rpc(name = "protocolVersion")]
	fn protocol_version(&self) -> Result<String>;

	#[rpc(name = "add")]
	fn add(&self, _: u64, _: u64) -> Result<u64>;

	#[rpc(name = "callAsync")]
	fn call(&self, _: u64) -> FutureResult<String, Error>;
}

struct RpcImpl;
impl Rpc for RpcImpl {
	fn protocol_version(&self) -> Result<String> {
		Ok("version1".into())
	}

	fn add(&self, a: u64, b: u64) -> Result<u64> {
		Ok(a + b)
	}

	fn call(&self, _: u64) -> FutureResult<String, Error> {
		future::ok("OK".to_owned()).into()
	}
}

fn main() {
     let mut io = IoHandler::new();
     let rpc = RpcImpl;

     io.extend_with(rpc.to_delegate());
}

发布/订阅示例

每个订阅必须具有 subscribeunsubscribe 方法。它们可以具有任何名称,但必须用 subscribeunsubscribe 进行注释,并具有匹配的唯一订阅名称。

use std::thread;
use std::sync::{atomic, Arc, RwLock};
use std::collections::HashMap;

use susy_jsonrpc_core::{Error, ErrorCode, Result};
use susy_jsonrpc_core::futures::Future;
use susy_jsonrpc_derive::rpc;
use susy_jsonrpc_pubsub::{Session, PubSubHandler, SubscriptionId, typed::{Subscriber, Sink}};

#[rpc]
pub trait Rpc {
   	type Metadata;

   	/// Hello subscription
   	#[pubsub(
		subscription = "hello",
		subscribe,
		name = "hello_subscribe",
		alias("hello_sub")
	)]
   	fn subscribe(&self, _: Self::Metadata, _: Subscriber<String>, _: u64);

   	/// Unsubscribe from hello subscription.
   	#[pubsub(
		subscription = "hello",
		unsubscribe,
		name = "hello_unsubscribe"
	)]
   	fn unsubscribe(&self, _: Option<Self::Metadata>, _: SubscriptionId) -> Result<bool>;
}


#[derive(Default)]
struct RpcImpl {
	uid: atomic::AtomicUsize,
	active: Arc<RwLock<HashMap<SubscriptionId, Sink<String>>>>,
}
impl Rpc for RpcImpl {
	type Metadata = Arc<Session>;

	fn subscribe(&self, _meta: Self::Metadata, subscriber: Subscriber<String>, param: u64) {
		if param != 10 {
			subscriber.reject(Error {
				code: ErrorCode::InvalidParams,
				message: "Rejecting subscription - invalid parameters provided.".into(),
				data: None,
			}).unwrap();
			return;
		}

		let id = self.uid.fetch_add(1, atomic::Ordering::SeqCst);
		let sub_id = SubscriptionId::Number(id as u64);
		let sink = subscriber.assign_id(sub_id.clone()).unwrap();
		self.active.write().unwrap().insert(sub_id, sink);
	}

	fn unsubscribe(&self, _meta: Option<Self::Metadata>, id: SubscriptionId) -> Result<bool> {
		let removed = self.active.write().unwrap().remove(&id);
		if removed.is_some() {
			Ok(true)
		} else {
			Err(Error {
				code: ErrorCode::InvalidParams,
				message: "Invalid subscription.".into(),
				data: None,
			})
		}
	}
}

依赖关系

~2.5MB
~55K SLoC