Based on what you said, you should be fine on the JS side.
You just have to update the ws_message exposed method in the canister to include a second argument with your message type, like we do in the tutorial:
To those who are following the Motoko websocket implementation, I have updated the examples as well, chat and pingpong, they are now using the JS SDK v0.2.2 and Motoko CDK v0.2.0. Messages are now being sent and received without explicit serialization and deserialization.
The CDKs now support multiple gateways! This means that you can now specify an array of gateway principals in the CDK initialization, and those will be the gateways authorized to interact with the canister.
For the Gateway, we’ve updated the IC WebSocket protocol to meet the latest requirements and we’ve added the tracing telemetry! We’re planning make a Jaeger UI dashboard publicly available.
Actions required
in JS, if you have any @dfinity/... dependency, make sure you upgrade/downgrade them to v0.20.1
upgrade both JS and canister libraries to the latest versions In case you can’t upgrade the@dfinity/...dependencies, installing the latest ic-websocket-js version usingnpm install ic-websocket-js@0.3.0 --forceshould work as a temporary fix.
if you’re using Rust in your canister, change the initialization of the WsInitParams to:
- let params = WsInitParams::new(handlers, gateway_principal);
+ let params = WsInitParams::new(handlers, vec![gateway_principal]);
and eventually include other gateways’ principals in the array.
if you’re using Motoko in your canister, change the IcWebSocketState initialization to:
- var ws_state = IcWebSocketCdk.IcWebSocketState(gateway_principal);
+ var ws_state = IcWebSocketCdk.IcWebSocketState([gateway_principal]);
and eventually include other gateways’ principals in the array.
That’s all you have to do!
You can also follow the updated tutorial for reference.
Motivation
Following our Proposal: Enable canisters to pay in ICP for external services, we are moving towards a more decentralized deployment of the gateways.
We’re now experimenting with Flux and we’ve already deployed some instances of the WS Gateway there. We will follow up with instructions on how to use those gateways as well.
The hosted gateway at gateway.icws.io will remain available.
We want to create a service in which canisters can pay for external services like servers, and we’re experimenting with Flux to do so.
In the case of IC WebSockets, we want to enable developers to simply pay some tokens to spin up their own IC WebSocket Gateway on Flux nodes. This way, the Gateway is not controlled by us and the developers do not have to self host it.
The latest version of IC4J WebSocket Agent library is out. It’s compatible with the latest Gateway spec. We also resolved the problem with keep alive messages, thanks @ilbert!
We suggest you to update all your SDKs to the latest version.
You don’t have to specify the gateway principals anymore in the parameters, the protocol handles it for you under the hood!
If you’re using Rust in your canister, change the initialization of the WsInitParams to:
- let params = WsInitParams::new(handlers, vec![gateway_principal]);
+ let params = WsInitParams::new(handlers);
If you’re using Motoko in your canister, import the new modules from the CDK and initialize it with:
import IcWebSocketCdk "mo:ic-websocket-cdk";
+ import IcWebSocketCdkState "mo:ic-websocket-cdk/State";
+ import IcWebSocketCdkTypes "mo:ic-websocket-cdk/Types";
actor class YourCansiter() {
+ let params = IcWebSocketCdkTypes.WsInitParams(null, null, null);
- var ws_state = IcWebSocketCdk.IcWebSocketState([gateway_principal]);
+ let ws_state = IcWebSocketCdkState.IcWebSocketState(params);
// on_open, on_message, on_close callbacks defined here...
- let handlers = IcWebSocketCdk.WsHandlers(
+ let handlers = IcWebSocketCdkTypes.WsHandlers(
?on_open,
?on_message,
?on_close,
);
- let params = IcWebSocketCdk.WsInitParams(
- handlers,
- null,
- null,
- null,
- );
- let ws = IcWebSocketCdk.IcWebSocket(ws_state, params);
+ let ws = IcWebSocketCdk.IcWebSocket(ws_state, params, handlers);
// expose the ws_... methods here
};
That’s all you have to do!
You can also follow the updated tutorial for reference.
Gateway
big refactoring of the gateway codebase, which involves the use of dashmap. Now a single state is shared across client session handlers and pollers.
the polling logic has been changed, so that if there are still messages in the canister’s queue, the poller immediately polls them, without waiting for the next polling iteration.
errors returned from the replica/canister during polling are handled in a better way, so that the poller is not always terminated when they occur