Page: Unichat WebSocket API
2019-11-21 11:11
Unichat WebSocket API
To access WebSocket api, first include somewhere in your HTML page the script to load the an Javascript API library from unichat site:
<script src="https://chat.mainnetwork.io/api/chat.js"></script>
It will load interface object you'll use to access unichat API functions and in turn provide your own functions for remote calls, such as notifications and error reportings.1
To start working, create unichat api object with:
val api = UniversaChatApi(settings, localInterface);
The settings object must contain at least { token: APP_DOMAIN_TOKEN }
field. The
real token value you'll get from the service administration,
see chat application domain. This function should only be called once,
the lost connection will be restored automatically, watch the localInterface
callbacks for it.
The localInterface
is an object providing callbacks for API events. You need
not implement all the callbacks and remote-callable procedures, only these
you need. For example:
val api = UniversaChatApi(
{
token: "test_token1"
},{
function onSocketConnected() {
console.log("<> connected event consumed");
},
function onDisconnected() {
console.log("<> disconnected event consumed");
},
function onInitialized() {
console.log("<> onInitialized called, api:", api);
api.ping({string: "hello1"}).then((result) => {
console.log("<> ping returns " + result.pong);
}).then(() => {
return api.version();
}).then((version) => {
console.log("api_version: " + version.version);
}).catch((reason) => {
console.log("<> FAILED call: " + reason);
});
}
}
Now let's see it in depth.
Important! Client software must properly handle reconnection. The API library will reconnect on itself, but the new connection looses log in state and software must then log in again using
auth_token
, without prompting the user.
We recommend to do it in onInitialized()
handler: check that there is login
token stored in the memory or lcal store, and login at this point. Note
that you can not yet do in in onSocketConnected()
as the protocol may not
be ready.
Settings
The only settings needed for the API user is token
that should be set to your
application's token.
Local interface
It's an object that provide a callback for the events and server-called procedures you need. When the server calls the local interface procedure that is not implemented, it just writes it to the log.
The following table shows some events and server-caller procedures:
name | type | description |
---|---|---|
onSocketConnected |
local event | the socket connection is established, but the local identity is not yet checked and API protocol is not ready. Do not call any API methods at this point |
onDisconnected |
local event | the websocket connection is dropped for any reason. Do not call any API method after this call |
onInitialized |
server call | the server side is ready to execute any API methods. This is a local interface tgat server calls when it's ready |
withTrace(callback) |
local method | calls the callback with API trace turned on (IO, etc). Allows temporarily turn on annoying API traces. |
UniChat API object
The object returned by the UniversaChatApi
is a main entry point to
call API methods. Among direct functional access to the remote methods it
provides has fields:
field name | description |
---|---|
appToken |
the application token used to connect to the API |
localInterface |
the interface provided on aPI object construction |
callByName |
method to call any API function by its name |
Remote interface
The api object
explained above provides direct access to all unichat API methods
just like ordinary javascript functions, which takes the single hash-like argument
with named parameters of the call and return the Promise
object which will
pass result in the same named parameters hash with value, returned from the
service.
For example, from our sample above:
api.ping({string: "hello1"}).then((result) => {
console.log("<> ping returns " + result.pong);
}).then( () => {
return api.version();
}).then( (version) => {
console.log("api_version: " + version.version);
});
Does the following:
- calls
ping(string: <string>) -> {pong: <string>}
unichat API method which returnspong
string value - if it is ok, calls
version() -> {version: string,...}
method and display version string.
So, in general, if the unichat API provides some function described as
do_something(foo: <string>,bar: <int>) -> {bazz: string}
It should be called through api
object as:
await doSomething({foo: "FOO", bar: 11})
where await is allowed, or by processing the returned Promise
, where it is not.
Notice that method names you can use as both camelCase or snake_case, the interface will convert it automatically. Instead, the case of arguments and returned parameters is always same as stated in declaration.
Errors
There are two flavors of errors: remote errors reported by the API and local errors caused by, for example, disonnected websocket. While both are reported with rejected promise, the rejection object is different.
Reporting error from API
If the service call returns error, the promise will be rejected with the following data:
{
class: exceptionClassName, // allow some extra diagnostics
code: string, // error code string, fixed
text: string // human-readable description, may vary
}
Usually, calling party should interpret only code
data, leaving text
message
just to simplify debugging process.
Se the sample above for catching promise rejection with unichat API error information.
Reporting local error
When local library fails to call remote API, it rejects the promise with an
custom UniversaError
exception object instance, which text represents the
error reason. As for now it could be:
disconnected
: command can't be excuted because of the connection absence. It is reported when the command being executed is interrupted by the connectino loss, or immediately if the api is called when the connection is not established.
Calling method by name
We discourage this approach, still it is possible to call any API method by name rather than directly. You should keep in mind that the ambiguity in your code reduces cleanness and readability of your code, hence increasing the support (and owning) costs of your project, this shortens its life and in a large perspective does no good to your record.
api.callByName(name, args={});
name
: string method name, with the same conversions applied as to the regular method name.args
: hash of named parameters.
This method also returns the Promise
which resolves to the possibilty hash of
named parameters that might be returned by the server.