IC WebSocket: Stable Release

I’ve upgraded to JS v0.2.2 and Motoko v0.2.2, upgraded the code on the canister and generated with dfx the files for the frontend

When creating new IcWebSocket(gatewayUrl, undefined, wsConfig); I get the following error:

ws_message method must have 2 arguments
at extractApplicationMessageIdlFromActor

Do i have to make another change for this new version besides adding the createWsConfig()?

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:

- public shared ({ caller }) func ws_message(args : IcWebSocketCdk.CanisterWsMessageArguments) : async IcWebSocketCdk.CanisterWsMessageResult {
-   await ws.ws_message(caller, args);
+ public shared ({ caller }) func ws_message(args : IcWebSocketCdk.CanisterWsMessageArguments, msg_type: ?MyMessage) : async IcWebSocketCdk.CanisterWsMessageResult {
+   await ws.ws_message(caller, args, msg_type);

You can also find an example in the docs of the IcWebSocket.ws_message method: https://mops.one/ic-websocket-cdk/docs/lib#IcWebSocket.ws_message.

I’ll also leave here the diff of the Rust example that shows what to change, which can be helpful.

Please remember to generate the JS declarations again after this change.


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.


IC WebSocket Gateway Docker image now available at omniadevs/ic-websocket-gateway! :tada:


New release, breaking changes!

Today we’re releasing new IC WebSocket versions that affect both the SDKs and the gateway.

:warning: With this release, the gateway hosted at gateway.icws.io will become incompatible with all clients running old SDKs versions! Please upgrade the SDKs!

New versions



What’s changed

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

  1. in JS, if you have any @dfinity/... dependency, make sure you upgrade/downgrade them to v0.20.1
  2. 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 using npm install ic-websocket-js@0.3.0 --force should work as a temporary fix.
  3. 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.
  4. 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.


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.


Is the experiment with the Flux Blockchain an isolated solution for Flux or is some integration with the IC?

1 Like

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.

I’d suggest you to have a look at the mentioned:


Updated Java WS Agent according the latest spec. Working with @ilbert to resolve some issues with Keep Alive message. Thanks Luca for your help!


Thanks to you Roman for integrating IC WebSocket in Java and enable many more potential applications to use 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!


New release!

Today we’re releasing new IC WebSocket versions that affect both the SDKs and the gateway.

New versions



What’s changed


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(

-   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.


  • 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
1 Like