Title: JSON-RPC 2.0 Post by: x3mike on September 13, 2016, 12:08:08 PM Hello,
what would be the suggestion to implement a JSON-RPC 2.0 Client? I tested several approaches using TCP-Client and HTTP-Client + ClientModule but had no luck. Thanks alot in advance! x3mike Title: Re: JSON-RPC 2.0 Post by: D.Tkalcec (RTC) on September 13, 2016, 12:23:32 PM Since JSON-RPC is HTTP-based, you can use TRtcHttpClient and TRtcDataRequest components on the Client to send requests and receive responses from the Server. To generate JSON content before preparing your request on the Client and to parse JSON responses received from the Server, you can use TRtcValueObject descendants (TRtcValue, TRtcRecord, TRtcArray, TRtcFunctionInfo, ...), or ... use some other classes or components to handle JSON data, or manually parse/generate JSON.
Best Regards, Danijel Tkalcec Title: Re: JSON-RPC 2.0 Post by: Max Terentiev on September 13, 2016, 04:07:03 PM I implemented JSON-RPC 2.0 support for RtcClientModule/RtcServerModule. It's requires some testing but at least it's works for me.
Don't know can I share changed files in this forum. I think Danijel should give me a permission. Title: Re: JSON-RPC 2.0 Post by: D.Tkalcec (RTC) on September 13, 2016, 06:50:57 PM You can post a unified diff file with all your modifications (compared to the latest RTC SDK version). Anyone with the latest RTC SDK version can use your diff file to update their local copy and include your changes. Unified diff files can be created using most Version Control systems (like SVN).
Best Regards, Danijel Tkalcec Title: Re: JSON-RPC 2.0 Post by: Max Terentiev on September 14, 2016, 01:25:51 PM Ok, I create patch: http://www.bspdev.ru/jsonrpc-patch.zip (http://www.bspdev.ru/jsonrpc-patch.zip)
Patch created using WinMerge software www.winmerge.org (http://www.winmerge.org) How to use: 1. Appy patach to RTC SDK sources. Version supported: RealThinClientSDK_v737_2016Q3.zip 2. Look at rtcDefs.inc, here is new define: {$DEFINE RTC_SUPPORT_JSONRPC}, enable it for JSON-RPC 2.0 support 3. Compile packages. Now you can select fmt_JSONRPC dataformat for RtcClientModule and RtcServerModule. Usage details: you can call remote functions same way as with fmt_RTC and fmt_XMLRPL with some exceptions: According to JSON-RPC 2.0 specification each json-rpc request should contain "id" with unique value. To set "id" for your requests you have this options: 1. TRtcClientModule.JsonRpcAutoId property. If set to true guid string will be generated and used as id automatically: {"jsonrpc": "2.0", "method": "myfunc", "params": [42, 23], "id": "{644e1dd7-2a7f-18fb-b8ed-ed78c3f92c2b}"} 2. TRtcFunctionInfo.JsonRpcRequestID property. Using this property you can set request id manually: with RtcClientModule1 do begin with Prepare('MyFunc') do begin JsonRpcRequestID:='myId12345'; .... end; end; it's produce request like this: {"jsonrpc": "2.0", "method": "myfunc", "params": [42, 23], "id": "myId12345"} If TRtcClientModule.JsonRpcAutoId=false and you not set id via TRtcFunctionInfo.JsonRpcRequestID - id field will be ommited. According to JSON-RPC 2.0 specification requests without "id" field will be considered as "notification" and empty response will be send from server (in case of errors to) ! Finally, request id must be unique if you send many requsts in batch using TRtcClientModule.StartCalls/Post. In case of duplicate exception will be raised. If your remote functions fails you can send back error by raising exception in your TRtcFunction.OnExecute handler. Error code and message must be in same string with # and : symbols as separators: raise Exception.Create('#25:MyFinc execute failed'); this generate response like this: {"jsonrpc": "2.0", "error": {"code": 25, "message": "MyFunc execute failed"}, "id": "myId12345"} It's inspired by current Danijel implementation ) Another important note: do not call delayed function in batch using StartCalls/Post ! It's not supported because responses must be also in batch but delayed function will send individual responses. Finally, here is one feature of json-rpc 2.0 wich is not implemented: if you send many requests in batch and one of request is bad: [{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"}, {"jsonrpc": "2.0", "method": "NotExists", "params": [1,2,4], "id": "2"}, // call of non exist remote function {"jsonrpc": "2.0", "method": "MyFunc", "params": [1,2,4], "id": "3"}] According to json-rpc 2.0 specification server must send responses for each request in batch. In my implementation server stop processing batch after first error. For example above they send response for request 1, send error response for request2 and skip request 3. It's caused by current Danijel's json parsing implementation (processing requests one by one and stop on any exception). It's can be fixed by pre-parsing entire batch but it's require complete rewrite of TRtcBaseServerModule.Call_DataReceived function. Enjoy ) Title: Re: JSON-RPC 2.0 Post by: D.Tkalcec (RTC) on May 05, 2017, 07:46:13 AM Just for the info ...
Starting with RTC SDK v8.00 (2017.Q2), a generic JSON format as well as JSON-RPC 1.0 and 2.0 formats are supported out-of-the-box with RTC Remote Functions and are now an integral part of TRtcClientModule and TRtcServerModule components (no patching required). With these new JSON-based formats introduced in TRtcClientModule and TRtcServerModule components, you can write and call remote functions with any JSON-based format the same way you can do it when using the RTC format (native to RTC SDK) or the XML-RPC format (introduced several years ago). To keep user code as independent as possible of data formats used in remote functions (RTC, XML-RPC or any JSON-based format), the "id" field required for "JSON-RPC 2.0" is always generated and exchanged automatically, so the only difference between XML-RPC and JSON formats will be the number of natively supported data types. Conversions between RTC data types and types supported by the data format being used are handled automatically, using the nearest native data type available, or a record structure with all the information included if no native data type is available (for example, when sending a TRtcDataSet). Best Regards, Danijel Tkalcec |