-
Notifications
You must be signed in to change notification settings - Fork 140
[Doc] QBit Microservice WebSocket wire protocol draft 01 JSON ASCII method batching RPC
QBit uses JSON and ASCII to form a wire protocol for sending messages in batches.
In progress. QBit has a working version of this specification. This protocol allows for high-speed invocation of methods. It does not use straight JSON to avoid double unencoding and double encoding JSON strings which can be CPU intensive.
QBit desires to be a cross platform microservice lib. This means that clients can/should/will be written in other languages. QBit supports REST/JSON however, there are speed limitations assocaited with request reply protocols like HTTP. Microservice uses REST/JSON as a great cross-platform multi-lingual service delivery which embraces polylingual/polyglot development.
QBit does not intend on being a Java only solution. There will/should be JavaScript and Python clients for example.
The reference implementation for QBit JSON WebSocket protocol is
io.advantageous.qbit.spi.BoonProtocolEncoder
and
io.advantageous.qbit.spi.BoonProtocolParser
.
If this draft specification is vague, the reference implementation is the final word.
Octet: 0 Description: Protocol Version Marker Required Value: 0x1c
This just marks the stream as a QJAC (QBit JSON ASCII Connection protocol)
Octet: 1 Description: Protocol Message Type Marker Supported values: 'a', 'g', 'r'
An 'm' means single method call A 'g' means a group of messages (events, method calls, and responses) An 'r' means a single response to a method call An 'e' means an event message
What comes next depends on if the message is an 'm', 'g', 'e', or 'r'.
Octet: 2
A group message is a collection of messages.
Each messages has a version since it is only one octet.
Octet: 0 Description: Protocol Version Marker Required Value: 0x1c
This just marks the stream as a QJAC (QBit JSON ASCII Connection protocol)
Octet: 1 Description: Protocol Message Type Marker Supported values: 'r', 'm', or 'e' (response, method call or event).
Octet: 2 Description: PROTOCOL_SEPARATOR Required Value: 0x1d
Beyond the third octet the values are separated by a PROTOCOL SEPARATOR 0x1d.
Messages within a group are delimited with PROTOCOL_MESSAGE_SEPARATOR (0x1f).
##Method Call Message
A method call consists of the following parts described in this JSON representation:
[preamble, messageId, address, returnAddress, headers, parameters,
objectName, methodName, timestamp, arguments]
Just like in the preamble described before delimiters are ASCII characters.
The major parts of the method call are delimited by PROTOCOL_SEPARATOR (0x1d).
The headers are delimited by PROTOCOL_KEY_HEADER_DELIM (0x1a), PROTOCOL_VALUE_HEADER_DELIM (0x15), PROTOCOL_ENTRY_HEADER_DELIM(0x19).
The parameters are also delimited by PROTOCOL_KEY_HEADER_DELIM (0x1a), PROTOCOL_VALUE_HEADER_DELIM (0x15), PROTOCOL_ENTRY_HEADER_DELIM(0x19).
The arguments for the method are delimited by PROTOCOL_ARG_SEPARATOR (0x1e).
Another way to look at a message with a JSON mindset is this:
[preamble, messageId, address, returnAddress, {'h1':'v1'}, {'p1':'v1'},
objectName, methodName, timestamp, [arg0, arg1, arg2]]
Headers, parameters, address, objectName, methodName, timestamp, and arguments are optional.
This is possible:
[preamble, null, address, returnAddress, {'h1':'v1'}, {'p1':'v1'},
objectName, methodName, null, null]
As is this:
[preamble, null, address, returnAddress, {'h1':'v1'}, {'p1':'v1'},
null, null, null, null]
Value 1 Description: Message ID Supported Value: a numeric usually sequential message identification number.
Value 2 Description: Address Supported Value: The "to address" where is the message going. Some form of URL.
Value 3 Description: Return address Supported Value: The "return address" where should responses to this message be sent. Some form of URL.
Value 4: Description: Headers Supported Value: Headers can contain additional routing or security tokens. Note: An empty headers section is just two repeated PROTOCOL SEPARATOR 0x1d.
A header can have multiple values:
Headers consist of key names with many values.
Each header is delimited by PROTOCOL_KEY_HEADER_DELIM (0x1a) and ends with PROTOCOL_ENTRY_HEADER_DELIM(0x19). Each key can have many values. Values are delimited by PROTOCOL_VALUE_HEADER_DELIM (0x15). Headers are like maps of JSON objects.
{
"Accept": ["jpeg", "gif", "png"],
"Name" : ["bob", 1]
}
Value 5: Description: Parameter Supported Values: Parameters are treated just like headers.
ASCII was picked to delimit headers and params so JSON string encoding and decoding would not need to be performed which can be expensive if you are sending millions of messages or reading million of messages from IO.
Value 6: Description: Object Name Supported Values: Name of the object we are invoking
This value could be empty if the address had enough information for the invocation. Or the address could be just the address of the module, and this is the object (or service name) inside of that module.
Value 7: Description: Method Name Supported Values: Name of the method on the object or service that we are invoking.
This value could be empty if the address had enough information for the invocation.
Value 8: Description: Timestamp Supported Values: Timestamp of when the method was sent
If this value is empty a timestamp will be generated on the server when the method is received and that will become the timestamp for the method.
Value 9: Description: Arguments Supported Values: Arguments to the method invocation.
Each argument is separated by a PROTOCOL_ARG_SEPARATOR (0x1e), and then converted into JSON copying the fields/properties from Java data value to a JSON object (map).
[PROTOCOL_PREAMBLE_VERSION, 'g',
[
[PROTOCOL_PREAMBLE_VERSION, 'a', {'header1':'value1'}
{'param1':'pvalue1'}, 'localhost:8080/module1',
'returnAddress', 'helloService', ["hi", "mom", 1]
],
[PROTOCOL_PREAMBLE_VERSION, 'a', {'header1':'value1'}
{'param1':'pvalue1'}, 'localhost:8080/module2',
'returnAddress', 'goodBye', ["goodbye", "mom", 1]
]
]
]
Address can be blank if method name, and object name is set. The returnAddress may be omitted if it is the same as the group ids return address.
##Response Message
A response typically to a method call.
[preamble, messageId, address, returnAddress, headers, parameters,
objectName, methodName, timestamp, wasErrors, responseMessage]
The messageId will match the messageId of the method call. The address will either be the address of the method call or the concatenation of "$address.$objectName.$methodName" or blank if the objectName, methodName are set.
The timestamp will also match the timestamp of the method call. wasErrors is true if the responseMessage represents an exception rather than a normal response.
Just like in the preamble described before delimiters are ASCII characters.
The major parts of the response are delimited by PROTOCOL_SEPARATOR (0x1d).
The headers are delimited by PROTOCOL_KEY_HEADER_DELIM (0x1a), PROTOCOL_VALUE_HEADER_DELIM (0x15), PROTOCOL_ENTRY_HEADER_DELIM(0x19).
The parameters are also delimited by PROTOCOL_KEY_HEADER_DELIM (0x1a), PROTOCOL_VALUE_HEADER_DELIM (0x15), PROTOCOL_ENTRY_HEADER_DELIM(0x19).
Value 1 Description: Message ID Supported Value: a numeric usually sequential message identification number. This will correlate to the method call for this response.
Value 2 Description: Address Supported Value: The "to address" where is the message going. Some form of URL.
Value 3 Description: Return address Supported Value: The "return address" where this responses should be sent. Can be some form of a URL.
Value 4: Description: Headers Supported Value: Headers can contain additional routing or security tokens. Note: An empty headers section is just two repeated PROTOCOL SEPARATOR 0x1d.
A header can have multiple values:
Headers consist of key names with many values.
Each header is delimited by PROTOCOL_KEY_HEADER_DELIM (0x1a) and ends with PROTOCOL_ENTRY_HEADER_DELIM(0x19). Each key can have many values. Values are delimited by PROTOCOL_VALUE_HEADER_DELIM (0x15). Headers are like maps of JSON objects.
Value 5: Description: Parameter Supported Values: Parameters are treated just like headers.
ASCII was picked to delimit headers and params so JSON string encoding and decoding would not need to be performed which can be expensive if you are sending millions of messages or reading million of messages from IO.
Value 6: Description: Object Name Supported Values: Name of the object we are invoking
This value could be empty if the address had enough information for the invocation. Or the address could be just the address of the module, and this is the object (or service name) inside of that module.
Value 7: Description: Method Name Supported Values: Name of the method on the object or service that we are invoking.
This value could be empty if the address had enough information for the invocation.
Value 8: Description: Timestamp Supported Values: Timestamp of when the method was sent
If this value is empty a timestamp will be generated on the server when the method is received and that will become the timestamp for the method.
Value 9: Description: was errors Supported Values: Is the body a response or an exception.
1 denotes there are errors 0 denotes that there are no errors.
Value 10: Description: response body Supported Values: The return value of the method call encoded as JSON.
##Event Message
An event is an unsolicited message to a consumer or subscriber.
[preamble, messageId, topic, headers, timestamp, messageBody]
The major parts of the response are delimited by PROTOCOL_SEPARATOR (0x1d).
The headers are delimited by PROTOCOL_KEY_HEADER_DELIM (0x1a), PROTOCOL_VALUE_HEADER_DELIM (0x15), PROTOCOL_ENTRY_HEADER_DELIM(0x19).
The parameters are also delimited by PROTOCOL_KEY_HEADER_DELIM (0x1a), PROTOCOL_VALUE_HEADER_DELIM (0x15), PROTOCOL_ENTRY_HEADER_DELIM(0x19).
Value 1 Description: Message ID Supported Value: a numeric usually sequential message identification number. This will correlate to the method call for this response.
Value 2 Description: Topic Supported Value: Typically some sort of unique string that identifies a topic that can be consumed or subscribed to.
Value 4: Description: Headers Supported Value: Headers can contain additional routing or security tokens. Note: An empty headers section is just two repeated PROTOCOL SEPARATOR 0x1d.
Each header is delimited by PROTOCOL_KEY_HEADER_DELIM (0x1a) and ends with PROTOCOL_ENTRY_HEADER_DELIM(0x19). Each key can have many values. Values are delimited by PROTOCOL_VALUE_HEADER_DELIM (0x15). Headers are like maps of JSON objects.
Value 5: Description: Timestamp Supported Values: Timestamp of when the method was sent
If this value is empty a timestamp will be generated on the server when the method is received and that will become the timestamp for the method.
Value 6: Description: event message body Supported Values: The body of the event encoded as JSON.
QBit Website What is Microservices Architecture?
QBit Java Micorservices lib tutorials
The Java microservice lib. QBit is a reactive programming lib for building microservices - JSON, HTTP, WebSocket, and REST. QBit uses reactive programming to build elastic REST, and WebSockets based cloud friendly, web services. SOA evolved for mobile and cloud. ServiceDiscovery, Health, reactive StatService, events, Java idiomatic reactive programming for Microservices.
Reactive Programming, Java Microservices, Rick Hightower
Java Microservices Architecture
[Microservice Service Discovery with Consul] (http://www.mammatustech.com/Microservice-Service-Discovery-with-Consul)
Microservices Service Discovery Tutorial with Consul
[Reactive Microservices] (http://www.mammatustech.com/reactive-microservices)
[High Speed Microservices] (http://www.mammatustech.com/high-speed-microservices)
Reactive Microservices Tutorial, using the Reactor
QBit is mentioned in the Restlet blog
All code is written using JetBrains Idea - the best IDE ever!
Kafka training, Kafka consulting, Cassandra training, Cassandra consulting, Spark training, Spark consulting
Tutorials
- QBit tutorials
- Microservices Intro
- Microservice KPI Monitoring
- Microservice Batteries Included
- RESTful APIs
- QBit and Reakt Promises
- Resourceful REST
- Microservices Reactor
- Working with JSON maps and lists
__
Docs
Getting Started
- First REST Microservice
- REST Microservice Part 2
- ServiceQueue
- ServiceBundle
- ServiceEndpointServer
- REST with URI Params
- Simple Single Page App
Basics
- What is QBit?
- Detailed Overview of QBit
- High level overview
- Low-level HTTP and WebSocket
- Low level WebSocket
- HttpClient
- HTTP Request filter
- HTTP Proxy
- Queues and flushing
- Local Proxies
- ServiceQueue remote and local
- ManagedServiceBuilder, consul, StatsD, Swagger support
- Working with Service Pools
- Callback Builders
- Error Handling
- Health System
- Stats System
- Reactor callback coordination
- Early Service Examples
Concepts
REST
Callbacks and Reactor
Event Bus
Advanced
Integration
- Using QBit in Vert.x
- Reactor-Integrating with Cassandra
- Using QBit with Spring Boot
- SolrJ and service pools
- Swagger support
- MDC Support
- Reactive Streams
- Mesos, Docker, Heroku
- DNS SRV
QBit case studies
QBit 2 Roadmap
-- Related Projects
- QBit Reactive Microservices
- Reakt Reactive Java
- Reakt Guava Bridge
- QBit Extensions
- Reactive Microservices
Kafka training, Kafka consulting, Cassandra training, Cassandra consulting, Spark training, Spark consulting