Closed rolandweber closed 6 years ago
General idea: For each incoming PDU, instantiate a stateful helper object. It gets access to the data received so far, and updates when more data comes in. It can tell:
There should be a factory interface to instantiate the helper. The factory is stateless and passed to the code that receives data. The helper itself is stateful, so that it can keep track of partially processed PDUs. In the case of TLVs, it can compute the length of the PDU once, as soon as the first four bytes are available.
Tracking data about partially received and processed PDUs isn't that important for TLVs. Computing the length from the two bytes in the header requires no significant effort. For the API design, however, it is important to keep the receiving classes and the interface of the helper independent of the wire format.
Imagine that the wire format is JSON. There is no header with a length. The logic must process JSON data and keep track of how many braces, brackets, double quotes, and escape sequences still need to be closed before the PDU is complete. You wouldn't want to process the JSON data from the start again every time a few more characters have been received. Therefore, the API must allow for stateful helpers.
In the JSON case, it would actually be helpful to fully parse the received data along the way, and then use it without parsing it again. Maybe an API for only detecting the end of a PDU, without parsing it, is not such a good idea after all? Implement a stream parser for PDUs instead?
YAGNI
Classes
SimplisticSocketHandler
on the server andMsgBoardClientHandlerImpl
on the client are supposed to be independent of the wire format. They use helper objects for parsing the received PDUs. However, both classes implement some limited TLV parsing in order to detect when a full PDU is received. Ideally, these classes should work without changes if the wire format is changed, for example to JSON instead of TLVs. Refactor the code to detect PDU boundaries. Implement a helper that can be used on both the server and the client. Keep the interface independent of the current TLV encoding. While TLVs provide the length of the PDU in the header, other formats might not. The helper should work equally well with blocking IO and asynchronous NIO.