CodeX Transport Protocol (CTProto) - is the presentation-layer of the OSI model for communication between services.
This is a JavaScript implementation example.
CTProto uses WebSockets as transport-layer.
After connection to the endpoint specified by application, you need to send the authorization message in 3 seconds. Otherwise, the connection will be closed.
All messages MUST fit next criteria:
- be a valid JSON-strings
- has the next structure:
field | type | purpose |
---|---|---|
messageId |
string | Unique message identifier. Create using the nanoid(10) method |
type |
string | Message action type. Related to business logic |
payload |
object | Any message data |
Example of a correct message:
"{\"messageId\":\"qUw0SWTeJX\",\"type\":\"update-workspace\",\"payload\":{\"name\":\"Example\"}}"
The first message after establishing the connection should be the authorize
.
If the server won't accept this message after 3 seconds after connection, it will close the connection.
Example of auth request:
{
"type": "authorize",
"messageId": "deo2BInCZC",
"payload": {
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
}
}
The payload
can contain any data that is used for authorization in your application. If auth will be successful, you will get a message with authorization data as a response. For example:
Example of auth response message:
{
"messageId": "deo2BInCZC",
"payload": {
"userId": "12345",
"workspaceIds": ["111", "222", "333"]
}
}
All errors will be sent to the client with structure like that:
{
"type": "error",
"payload": {
"error": "Example of the error message"
},
"messageId": "3eo11IpiZC"
}
To use CTProto JavaScript server implementation, follow the next guide.
Install a package
yarn add ctproto
Then, configure the server
import { CTProtoServer } from 'ctproto';
const transport = new CTProtoServer({
port: 4000,
path: '/client',
async onAuth(authRequestPayload){
const user = aurhorizeUser(authRequestPayload)
if (!user) {
throw new Error('Wrong auth payload');
}
return {
user
};
},
async onMessage(message) {
// massage handling
},
});
Where
option | type | description |
---|---|---|
onAuth |
(authRequestPayload: AuthRequestPayload) => Promise | Method for authorization. See details below |
onMessage |
_(message: NewMessage) => Promise<void | object>_ |
and you can set any ws.Server options.
This callback will contain your application authorization logic. It will accept the payload of the authorize
request.
You can implement your own authorization logic in there, such as DB queries etc.
This method should return authorized client data, such as user id and so on. This data will be returned to client with the next response message.
Also, this data will be saved as authData
for this connected client under the hood of the protocol.
You can query it later, for example for sending messages to some connected clients:
const workspaceId = '123';
transport
.clients
.find((client: Client) => client.authData.workspaceIds.includes(workspaceId))
.send('workspace-updated', { workspace });
This callback will be fired when the new message accepted from the client. It will get a whole message object as a param.
You can handle a message and optionally you can return a value (object
) to respond on this message.
To use CTProto JavaScript client implementation, follow the next guide.
Install a package
yarn add ctproto
Then, configure the client
import { CTProtoClient } from 'ctproto';
const client = new CTProtoClient({
apiUrl: 'ws://localhost:8080',
authRequestPayload: {
token: 'asd',
},
onAuth: (data) => {
if (!data.success) {
throw new Error(`${data.error}`);
}
console.log('Authorization is success', data.success);
},
onMessage: (data) => {
console.log('Incomming message: ', data);
}
});
Where
option | type | description |
---|---|---|
apiUrl |
string | Requests will be made to this API. |
authRequestPayload |
AuthRequestPayload | Authorization request payload. |
onAuth |
(payload: AuthResponsePayload) => void | Method for handling authorization response. See details below |
onMessage |
(message: ApiUpdate) => void | Method for handling message initialized by the server. See details below |
This callback will contain your application authorization response handler. It will accept the payload of the authorize response.
You can implement your own authorization response handler in there.
This callback will be fired when an ApiUpdate
(new message initialized by the server) accepted from the server. It will get a message object as a param.
You can send a request and get a response:
client
.send(type, payload)
.then((responsePayload) => {
// do something with the response payload
});
Where
parameter | type | description |
---|---|---|
type |
ApiRequest['type'] | Type of available request. |
payload |
ApiRequest['payload'] | Request payload. |
responsePayload |
ApiResponse['payload'] | Response payload. |
Example
client
.send('sum-of-numbers', {
a: 10,
b: 11,
})
.then((responsePayload) => {
console.log('Response: ', responsePayload);
});
If you're using TS, you will need to create interfaces describing some CTProto objects: AuthorizeMessagePayload
, AuthorizeResponsePayload
, ApiRequest
, ApiResponse
, ApiUpdate
.
Type | Description | Example |
---|---|---|
AuthorizeMessagePayload |
Payload of your authorize message. See Authorization. |
Example: /example/types/requests/authorize.ts |
AuthorizeResponsePayload |
Payload of the response on your authorize message. See Authorization. |
Example: /example/types/responses/authorize.ts |
ApiRequest |
All available messages that can be sent from the Client to the Server | Example: /example/types/index.ts |
ApiResponse |
All available messages that can be sent by the Server in response to Client requests | Example: /example/types/index.ts |
ApiUpdate |
All available messages that can be sent by the Server to the Client | Example: /example/types/index.ts |
All examples see at the /example directory.
CodeX is a team of digital specialists around the world interested in building high-quality open source products on a global market. We are open for young people who want to constantly improve their skills and grow professionally with experiments in cutting-edge technologies.
๐ | Join ๐ | ||
---|---|---|---|
codex.so | codex.so/join | @codex_team | @codex_team |