• 沒有找到結果。

3 Solution proposal

3.7 Current implementation

Currently the implementation has been accomplished to cover Layer 1 and partially Layer 2. The implementation has been made in Delphi dialect of Object Pascal language, and compiled for Windows family operating systems. The source code with precompiled demo is attached to this thesis on a CD. The original feature of this implementation is that the virtual hosting for variables and function calls functionality is combined with the

54

parsing functionality.

3.7.1 libEngine.pas

This library is introducing most important classes for embedding API Operator component within existing code. It is also initializing key components to set up the API Operator environment automatically at the runtime, in the moment when the library is loaded. The code is very short:

unit libEngine;

55

//Supported Types:

SupportedTypes.Free;

end.

The important code is inside the INITIALIZATION section. SupportetTypes object defines data types supported by the framework and their lexical identifiers. In the current implementation there are only two supported types:

string and integer. End-user might implement conversion routines for encoding additional types within existing ones, for example, encoding float values as string, or Boolean values as either string or integer. Naturally, more types can be added to the native support, and they would need to be initialized in this library as well.

The GlobalVariables object is managing the virtual memory and variable allocation within the API Operator. The constructor of the class requires reference to previously configured SupportedTypes object, so that the memory manager knows what data types can be allocated as variables.

The HostedFunctions object is for allocationg and managing dynamically exported RPC calls. The class’ constructor requires reference to both GlobalVariables and SupportedTypes objects so that it can carry out type control and variable substitution during the interpretation of the RPC calls, which are plain-text encoded instructions. It is important to note, that these objects will only host functions and variables in the local memory space, so only functionality exported from within the application hosting the API Operator component. A different set of classes is responsible for managing actual remote calls.

3.7.2 libSupportedTypes.pas

This library provides with classes needed to implement natively supported data

56

types. Every data type to be natively supported is a class inheriting from TSupportedType mother class. One important element for any natively supported type is built-in conversion to and from the plain-text string type.

This are virtual methods, that have custom implementations for each supported data type. These methods are used during the interpretation of the RPC code, when the plain-text lexems are passed to check whether or not the conversion is possible, which is the actual delivery of type control functionality.

3.7.3 libHostedVariables.pas

This library provides with a class TVarTable, which allows for allocating memory for storing data of natively supported types, as variables indexed by plain-text identifiers. Each virtual variable is encapsulated within a very simple record:

that holds 3 member fields: TypeFlag, which is code-level flag assigned to a natively-supported type, TypeID, which is a plain-tex unique identifier of the data type for use on the RPC code level, and the Value field, which is a reference to an object of TSupportedType class that implements interface to access (reading, writing and conversions) the actual data, and which itself allocates the actual memory for storing the data. The TVarTable class allows for accessing variables and their data by the TypeID and is being a part of the interpreter itself. In other words, not only it serves as an interface for accessing the hosted variables, but also provides with basic set of methods for parsing

57

plain-text encoded lexems for verifying whether or not they refer to actual variables.

3.7.4 libHostedFunctions.pas

This library provides with classes for hosting RPC calls, even though in the case of API Operator component they also host locally exported functions, that do not require any network traffic to be executed.

Important low-level class in this library is TFunctionPrototype, which implements support for custom formats of function calls, including function identifiers and description of required arguments (if any). This class allows for creating a prototype for a function call at the run-time. It is contained by a higher-level THostedFunction class that not only allows for accessing the interface for executing the actual call, but also implements methods for parsing the plain-text encoded function calls. Above this class, there is a higher-level THostedFunctions class which manages a collection of THostedFunction objects. A very important definition from this library is TExternalCallEvent:

TExternalCallEvent = Procedure(const FunctionName: widestring; const Arguments:

TVarTable; const ArgCount: cardinal; var FunctionResult: widestring; const ResultType: widestring; const RessultFlag: TTypeFlag)of object;

This is a procedural type, which define a generic and universal wrapper for exporting ANY function or procedure (function without result, void in C language) from the host application. This is not however, the final data type that the developer uses for coding wrappers, as there is a higher-level simplified version defined, that will be discussed later. The definition in this library requires few arguments in the wrapper:

FunctionName – is a plain-text encoded unique identifier for a function

Arguments – is a reference to the local object of TVarTable class allocating

58

memory for storing and handling function arguments, that exists only throughout the call of the function, and is being released after the call executes.

FunctionResult – is a string variable for returning plain-text encoded result value (it will be later converted to a proper type that is natively supported) ResultType – is a plain-text encoded identifier of the supported type of which the function result is expected to be

ResultFlag – is the code-level flag with the same purpose as the ResultType, but easier to use in the statements and expressions, as it is a simple type comparing to string.

3.7.5 libErrors.pas

This unit contains error codes that the built-in interpreter can return to end user via the RPC gate. Additionally it contains few functions shared across other modules for parsing of plain text and HTML, as well as some system-defined constants that are the standard setup of some core configuration of the system.

3.7.6 Server/client vs. Operator/Contributor vs. Flavors

This might be a confusing portion of the architecture, if not explained.

Essentially neither the API Operator nor API Contributor component is determined to be strictly corresponding to either a server or client role. Either of the two components might incorporate multiple servers as well as multiple clients within. The only certain thing following the system specification is that the API Operator will at least have one active server opened, thru which API Contributors can announce their presence in the network by default, and thru which an End-user default interface (RPC gate) is accessible via http protocol.

The term API Operator and API Contributor only refers to the role in the

59

system, according to the earlier description in this chapter.

The API Contributor may come in many different variants, so called flavors.

The simplest flavor is only incorporating a Client connection, and such API Contributor will use pooling to check with the API Operator if there are any pending RPC requests. When API Operator executes RPC via this flavor, the timeout delay is used for the API Contributor to pool for awaiting RPC calls, and for the second following pooling that will pass the result statuses of the previous queue of RPC calls. This flavor is dedicated to embed API Contributor components on devices on which CPU usage saving is crucial.

Pooling saves lot of CPU usage and therefore also power usage when comparing to a server connection that is left open..

Other flavor is incorporating a server connection, and RPC calls invoked on this flavor of API Contributor have fewer critical stages during which a connection/network error may interrupt the normal RPC flow (RPC call + ACK roundtrip). The API Operator will only need to open a client connection to the API Contributor once, and together with submitting the RPC call fetch the result status, just like a web browser is requesting a webpage directly after submitting GET or POST request with specified headers and query string parameters. The ACK can be obtained within a single roundtrip, versus a double roundtrip in the case of the first introduced flavor. Also the tolerance for delay may be lower, as there is no need for queuing RPC calls and waiting for the API Contributor to fetch them via pooling.

Additionally to the above obvious flavors, hybrid flavors are also possible if a specific application needs it.

Although the second described flavor is less vulnerable to connection/network

60

errors during the RPC call roundtrip (RPC call + ACK), but it also exploits the API Operator to a greater degree, requiring more client connections to be dynamically managed, therefore each flavor has its own advantages as well as disadvantages.

API Operator also comes in multiple flavors, however in this case it more often refers to the amount of server connection opened for supporting different protocols, like HTML, XML, JSON etc.

3.7.7 libServerMod_HTTP.pas as a flavor of API Operator

This library defines classes for the default flavor of API Operator component, which uses HTTP protocol. This flavor incorporates THTTPServer class responsible for adding active server connection that the end-user will be able to directly access via web browser, on a custom port. This flavor implements methods of the http server object with a basic authentication mechanism, that will require end user to use a login and password to access the default interface (RPC gate).

Additionally, the very same flavor supports a plain-text based communication, after not finding valid HTTP protocol header in the incoming connection. This is used by default by API Contributors when connecting to the API Operator, and allows for providing both the user interface and the default RPC channel over the same active service.

Use of this flavor implies use of a CSS file in the home directory of the API Operator host application, that will be used (if present) to load styling for the HTML based user interface. The CSS file has to be called NETPASKAL.CSS, and the naming comes from an older programming project that the discussed system was implemented upon, that dates back to the project for my Bachelor

61

thesis at Adam Mickiewicz University in Poland.

3.7.8 libMemberTCPLite.pas as a flavor of API Contributor

This library defines classes for the default flavor of API Contributor component. It incorporates a client connection and a timer, that will trigger pooling to the API Operator component over TCP/IP (either over network or local host). It is the lightest flavor for the API Contributor, and uses the plain-text communication over the default channel, through which the HTTP access to the default end user interface is also provided. Any other flavor of the API Contributor would inherit form this flavor and use the default channel to set up a custom one(s) and hand over the further communication.

3.7.9 Extending flavors

Flavors might be added as modules (for example as DLL libraries for Windows-based API Operators) and can add communication channels and protocols over which RPC transactions can be carried out. For example, a flavor enabling IPC messaging can be added, for handling RPC transactions via IPC channel rather than network connection via sockets. This may be a faster alternative for handling API Contributors residing in the local host in relation to API Operator. Above the level of the flavor’s internal implementation there is no difference and the RPC transactions become scalable transparently.

3.7.10 uAnLex.pas

This library implements a Lexical analyzer used in the process of parsing RPC calls and EUD programming scripts. The code was originally implemented for my Bachelor’s thesis at Adam Mickiewicz University in Poland, and somewhat upgraded since then for more convenient use and less memory consumption.

62

相關文件