연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.
Deeplink RPC
A RPC-via-deeplink communication library coded in Dart.
This is dedicated to Flutter mobile applications (iOS / Android).
Protocol
Deeplink codec
Deeplink messages are appended to the deeplink URI. Because of that, there are limitations in the available formatting.
To get it working, the message is encoded that way :
+--------------+ +------+ +-----------+
method_payload : | Json Message |-> | gzip |-> | base64Url |
+--------------+ +------+ +-----------+
Deeplink Url : `<scheme>:
Example :
+--------------------------+ +----------------------------------------------------------------+
method_payload : | { "param1" : "a_value" } |----> | "H4sIAAAAAAAAA6tWUCpILErMNVRSsFJQSowvS8wpTVVSqAUAhIgKchgAAAA=" |
+--------------------------+ +----------------------------------------------------------------+
Deeplink Url : `scheme:
Request formatting
Requests payload are encapsulated in a JSON-RPC 2.0 message.
{
"id": Number,
"replyUrl": String,
"params": {
"origin": {
"name": String,
"url": String | undefined,
"logo": Base64 | undefined,
},
"version": 2,
"payload": Object,
}
}
Success Response formatting
{
"id": Number,
"result": Object,
}
Failure Response formatting
{
"id": Number,
"failure": {
"code": Number,
"message": String | undefined,
"data": Object | undefined,
},
}
Usage
Server - listening to incoming requests
final _deeplinkRpcServer = DeeplinkRpcServer()
..registerHandler(
DeeplinkRpcRequestHandler(
route: const DeeplinkRpcRoute('a_rpc_command'),
handle: (request) {
log('Command received');
}
),
);
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'DeeplinkRPC Demo',
home: const SendForm(),
onGenerateRoute: (settings) {
if (_deeplinkRpcServer.handleRoute(settings.name)) return;
return null;
},
);
}
}
Client - Sending requests and listening for responses
final _deeplinkRpcClient = DeeplinkRpcClient();
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'DeeplinkRPC Demo',
onGenerateRoute: (settings) {
if (_deeplinkRpcClient.handleRoute(settings.name)) return;
return null;
},
home: Scaffold(
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.send),
onPressed: () async {
final response = await _deeplinkRpcClient.send(
timeout: const Duration(seconds: 5),
request: DeeplinkRpcRequest(
requestUrl: 'serverapp://server.app/request_endpoint',
replyUrl: 'clientapp://client.app/reply_endpoint',
params: {
'param1': 'value1',
'param2': 'value2',
},
),
);
response.map(
failure: (failure) {
log(
'RPC request failed',
error: failure,
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(failure.message ?? "An error occured")),
);
},
success: (result) {
log(
'RPC request succeed : ${json.encode(result)}',
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(json.encode(result))),
);
},
);
},
),
body: const SafeArea(
child: Padding(
padding: EdgeInsets.all(8.0),
child: Center(
child: Text('Client example'),
),
),
),
),
);
}
}