Interpretation of json-rpc 1.0 specifications
JSON may be the simplest text data format on the earth. It is readable, flexible, and has a small amount of data. It is easy to codec and fast, and supports Unicode and special characters. By comparing XML, we can see how many bytes are wasted on various additional tag nodes. By default, JSON characters must be in the Unicode format. All non-accios can be represented by \ uXXXX without additional escape. In contrast, XML requires escaping, CDATA (like the PRE Tag in HTML), or Base64 to represent special data. Of course, the disadvantage is also obvious. It is much larger than the binary data structure, and the codec is slow. It does not have a complete type system, and its presentation capability is limited.
JSON-RPC is a Remote Process Call (RPC) technology that uses json objects as data carriers.
"Does distributed computing have to be any harder than this? I don't think so. "-- Jan-Klaas Kollhof
JSON-RPC design goals are two words:Simple. We know that an rpc framework is used for interactive communication between two systems. Therefore, an intermediate data transmission format needs to be defined. To convert to the platform data structure used by the system, a set of serialization and deserialization functions are required. Then, some communication protocol is required to transmit the actual remote call data. Finally, stub & skeleton at both ends of the communication need to be implemented. This is generally based on the dynamic proxy or the proxy implemented by AOP and an interface structure that can be called, so that the Framework hides all other technical details (data format, serialization, network transmission, etc.), the program can call remote methods like local method calls. Summary:
- Data format
- Serialization Function
- Communication Protocol
- Code Pile
The JSON-RPC specification explicitly specifies only the data format (JSON), the communication protocol (TCP or HTTP) is recommended, serialization and code pile are not mentioned. Of course, serialization is easy to handle. There are abundant JSON serialization libraries in various languages (see reference 1 ). Then the code pile is completely reserved for the framework to implement the JSON-RPC specification to handle it, the specific processing of the communication protocol also needs to be considered by the framework itself.
We know that the communication between the two systems may be synchronous blocking (each request sends the next request after the response is complete), or asynchronous non-blocking (request 1 is complete, continue sending request 2, and process the response when the response is returned). It may also be unidirectional (one-way, no matter if it is sent, and no response is required ), it may also be request-response. Each request must have an explicit response.
In the JSON-RPC1.0, the two sides of the communication are treated as two equal ends.
- Defines how to send requests, return results, and error messages,
- How to deal with the interaction process of one-way and request-response,
- And how two-way asynchronous requests match results and requests,
- Finally, a simple class hinting Extension function is added (the idea is good, but there are no details in just two sentences, which is quite tricky ).
Let's take a look at the specific content of the Specification.
Request)The requester sends a JSON object to indicate the method to be called. The example is as follows:
{ "method": "echo", "params": ["Hello JSON-RPC"], "id": 1}
It contains three key elements:
- Method: indicates the method to be called.
- Params: array of parameters
- Id: indicates that the request needs to be responded. The service provider must provide a response with the same id as 1.
This id field is very interesting. Generally, synchronous RPC does not need to consider this, because under normal circumstances, an RPC request only contains one request, and the request will wait for the response information to return, before that, the caller's processing thread will be blocked, so that the entire RPC is like a local method called.
Response)A typical response information is as follows:
{ "result": "Hello JSON-RPC", "error": null, "id": 1}
There are also three key elements:
- Result: indicates the returned result. If an error occurs, the result must be null.
- Error: indicates an error. If the request is successful, the error must be null.
- Id: indicates the notification of the corresponding request id for this response)
The notification information is similar to a request, but the id must be null. The notification representative has one-way requests and cannot reply. It can be sent to the service provider by the requester or the service provider to the requester. (in principle, both parties are required to be equal in the agreement, either the requester or the service provider, in this regard, HTTP is actually not satisfied ).
Communication (transport)
- TCP
It is recommended that the communication parties use byte stream for interaction under TCP. At this time, both parties are equal. Before closing the connection, you must send an error message to all non-responding requesters. Invalid requests or responses will close the connection.
- HTTP
HTTP can also be used as the communication protocol under some restrictions. At this time, the communication parties are obviously not equal, with the client and server.
Considering the HTTP overhead, the Protocol allows multiple rpc requests or notifications to be carried at one POST. Because the server cannot actively access the client in HTTP, the server can attach its own requests and notifications to the HTTP response. The local protocol did not clarify the specific operations, and the details were also a pain point.
Class hinting)It is very simple, that is, adding an attribute to indicate the constructor.constructor, You can use parameters[param1,...]To initialize the object. And if the constructor is called during object initialization, the corresponding attributes (suchprop1) Will also be added to the object, sample code:
{"__jsonclass__":["constructor", [param1,...]], "prop1": ...}
The Protocol is not specific about this place, how to operate it, how it corresponds to the type in the native environment, and how it hurts ++.
Example of multiple communicationsJSON-RPC process is as follows, where-->Send data to the service provider,<--Response on behalf of the service provider:
--> {"method": "postMessage", "params": ["Hello all!"], "id": 99}<-- {"result": 1, "error": null, "id": 99}<-- {"method": "handleMessage", "params": ["user1", "we were just talking"], "id": null}<-- {"method": "handleMessage", "params": ["user3", "sorry, gotta go now, ttyl"], "id": null}--> {"method": "postMessage", "params": ["I have a question:"], "id": 101}<-- {"method": "userLeft", "params": ["user3"], "id": null}<-- {"result": 1, "error": null, "id": 101}
Further discussion on JSON-RPC1.0 specifications
- About notifications
The notification mechanism can also be used for NOOP similar to the FTP protocol or the Keep Alive heartbeat mechanism in other communication protocols. During the specific use process, a notification is sent regularly to confirm that both parties are online and that information with asynchronous processing can be merged.