Skip to content

Tutorial

This tutorial demonstrates how to use XConn across multiple programming languages.

Prerequisites

Before creating or running a client, you must have a WAMP router running. The client needs to connect to a router to send and receive messages, so this step is essential.

We recommend using a NXT router, a lightweight and high-performance WAMP router built for flexibility and speed.

Installation

go get github.com/xconnio/xconn-go
uv pip install xconn

Dart

dart pub add xconn

Flutter

flutter pub add xconn

To install xconn-swift, add the following to your Package.swift file:

Swift

    let package = Package(
        dependencies: [
            .package(url: "https://github.com/xconnio/xconn-swift.git", branch: "main"),
        ],
        targets: [
            .executableTarget(name: "<executable-target-name>", dependencies: [
                .product(name: "XConn", package: "xconn-swift"),
            ]),
        ]
    )

To install xconn-rust, add the following to your Cargo.toml file:

Rust

[dependencies]
xconn = { git = "https://github.com/xconnio/xconn-rust", branch = "main" }

To install xconn-kotlin, add the following in your build.gradle file:

Kotlin

dependencies {
    implementation("io.xconn:xconn:0.1.0-alpha.3")
}

To install xconn-js, add the following in your package.json file:

JavaScript

"dependencies": {
    "xconn": "github:xconnio/xconn-ts#13fbafb2c8e1e30a1cf13803fd207f5705270e24"
}

Session Creation

package main

import (
    "context"
    "log"

    "github.com/xconnio/xconn-go"
)

func main() {
    session, err := xconn.ConnectAnonymous(context.Background(), "ws://localhost:8080/ws", "realm1")
    if err != nil {
        log.Fatal(err)
    }
}

Synchronous Session

from xconn.session import Session
from xconn.client import connect_anonymous

session: Session = connect_anonymous("ws://localhost:8080/ws", "realm1")

Asynchronous Session

from xconn import run
from xconn.async_session import AsyncSession
from xconn.async_client import connect_anonymous

async def main():
    session: AsyncSession = await connect_anonymous("ws://localhost:8080/ws", "realm1")

if __name__ == "__main__":
    run(main())

import "package:xconn/xconn.dart";

void main() async {
  var session = connectAnonymous("ws://localhost:8080/ws", "realm1");
}
import XConn

let client = Client()
let session = try await client.connect(uri: "ws://localhost:8080/ws", realm: "realm1")

Synchronous Session

use xconn::sync::client::connect_anonymous;

fn main() {
    let session = connect_anonymous("ws://localhost:8080", "realm1").unwrap_or_else(|e| panic!("{e}"));
}

Asynchronous Session

use xconn::async_::client::connect_anonymous;

#[tokio::main]
async fn main() {
    let session = connect_anonymous("ws://localhost:8080/ws", "realm1")
        .await
        .unwrap_or_else(|e| panic!("{e}"));
}

package io.xconn

import io.xconn.xconn.connectAnonymous
import kotlinx.coroutines.runBlocking

fun main() =
    runBlocking {
        val session = connectAnonymous("ws://localhost:8080/ws", "realm1")
    }
import {connectAnonymous} from "xconn";


async function main() {
    const session = await connectAnonymous("ws://localhost:8080/ws", "realm1")
}

main().catch((err) => {
    console.error("Error:", err);
});

Subscribe to a topic

func exampleSubscribe(session *xconn.Session) {
subscribeResponse := session.Subscribe("io.xconn.example", eventHandler).Do()
if subscribeResponse.Err != nil {
    log.Fatalf("Failed to subscribe: %v", subscribeResponse.Err)
}
}

func eventHandler(evt *xconn.Event) {
    fmt.Printf("Event Received: args=%s, kwargs=%s, details=%s", evt.Args, evt.Kwargs, evt.Details)
}

Synchronous

from xconn.types import Event
from xconn.session import Session

def example_subscribe(session: Session):
    session.subscribe("io.xconn.example", event_handler)


def event_handler(event: Event):
    print(f"Event Received: args={event.args}, kwargs={event.kwargs}, details={event.details}")

Asynchronous

from xconn.types import Event
from xconn.async_session import AsyncSession

async def example_subscribe(session: AsyncSession):
    await session.subscribe("io.xconn.example", event_handler)


async def event_handler(event: Event):
    print(f"Event Received: args={event.args}, kwargs={event.kwargs}, details={event.details}")

void exampleSubscribe(Session session) async {
  await session.subscribe("io.xconn.example", eventHandler);
}

void eventHandler(Event event) {
  print("Received Event: args=${event.args}, kwargs=${event.kwargs}, details=${event.details}");
}
func exampleSubscribe(_ session: Session) {
    try await session.subscribe(topic: "io.xconn.example", endpoint: eventHandler)
}

func eventHandler(_ event: Event) {
    print("Event received: args=\(event.args), kwargs=\(event.kwargs), details=\(event.details)")
}

Synchronous

use xconn::sync::session::Session;
use xconn::sync::types::{Event, SubscribeRequest};

fn example_subscribe(session: Session){
    let subscribe_request = SubscribeRequest::new("io.xconn.example", event_handler);
    match session.subscribe(subscribe_request) {
        Ok(response) => println!("{response:?}"),
        Err(e) => println!("{e}"),
    }
}

fn event_handler(event: Event) {
    println!(
        "Event Received: args={:?}, kwargs={:?}, details={:?}",
        event.args, event.kwargs, event.details
    );
}

Asynchronous

use xconn::async_::session::Session;
use xconn::async_::types::{Event, SubscribeRequest};

async fn example_subscribe(session: Session) {
    let subscribe_request = SubscribeRequest::new("io.xconn.example", event_handler);
    match session.subscribe(subscribe_request).await {
        Ok(response) => println!("{response:?}"),
        Err(e) => println!("{e}"),
    }
}

async fn event_handler(event: Event) {
    println!(
        "Event Received: args={:?}, kwargs={:?}, details={:?}",
        event.args, event.kwargs, event.details
    );
}

suspend fun exampleSubscribe(session: Session) {
    session.subscribe("io.xconn.example", { event ->
        print("Event Received: args=${event.args}, kwargs=${event.kwargs}, details=${event.details}")
    }).await()
}
import {Event, Session} from "xconn";


async function exampleSubscribe(session: Session) {
    const onEvent = (event: Event) => {
        console.log(`Received Event: args=${event.args}, kwargs=${event.kwargs}, details=${event.details}`);
    };

    await session.subscribe("io.xconn.example", onEvent);
}

Publish to a topic

func examplePublish(session *xconn.Session) {
publishResponse := session.Publish("io.xconn.example").Arg("test").Kwarg("key", "value").Do()
if publishResponse.Err != nil {
    log.Fatalf("Failed to publish: %v", publishResponse.Err)
}
}

Synchronous

from xconn.session import Session

def example_publish(session: Session):
    session.publish("io.xconn.example", ["test"], {"key": "value"})

Asynchronous

from xconn.async_session import AsyncSession

async def example_publish(session: AsyncSession):
    await session.publish("io.xconn.example", ["test"], {"key": "value"})

void examplePublish(Session session) async {
  await session.publish("io.xconn.example", args: ["test"], kwargs: {"key": "value"});
}
func examplePublish(_ session: Session) {
    try await session.publish(
        topic: "io.xconn.example",
        args: ["test"],
        kwargs: ["key": "value"],
    )
}

Synchronous

use xconn::sync::session::Session;
use xconn::sync::types::PublishRequest;

fn example_publish(session: Session) {
    let publish_request = PublishRequest::new("io.xconn.example")
        .arg("test")
        .kwarg("key", "value");

    match session.publish(publish_request) {
        Ok(response) => println!("{response:?}"),
        Err(e) => println!("{e}"),
    }
}

Asynchronous

use xconn::async_::session::Session;
use xconn::async_::types::PublishRequest;

async fn example_publish(session: Session) {
    let publish_request = PublishRequest::new("io.xconn.example")
        .arg("test")
        .kwarg("key", "value");

    match session.publish(publish_request).await {
        Ok(response) => println!("{response:?}"),
        Err(e) => println!("{e}"),
    }
}

suspend fun examplePublish(session: Session) {
    session.publish("io.xconn.example", args = listOf("test"), kwargs = mapOf("key" to "value"))?.await()
}
import {Session} from "xconn";


async function examplePublish(session: Session) {
    await session.publish("io.xconn.example", {args: ["test"], kwargs: {"key": "value"}});
}

Register a procedure

func exampleRegister(session *xconn.Session) {
registerResponse := session.Register("io.xconn.echo", invocationHandler).Do()
if registerResponse.Err != nil {
    log.Fatalf("Failed to register: %v", registerResponse.Err)
}
}

func invocationHandler(ctx context.Context, inv *xconn.Invocation) *xconn.InvocationResult {
    return xconn.NewInvocationResult()
}

Synchronous

from xconn.session import Session
from xconn.types import Invocation

def example_register(session: Session):
    session.register("io.xconn.echo", invocation_handler)


def invocation_handler(invocation: Invocation):
    print(f"Received args={invocation.args}, kwargs={invocation.kwargs}, details={invocation.details}")

Asynchronous

from xconn.types import Invocation
from xconn.async_session import AsyncSession

async def example_register(session: AsyncSession):
    await session.register("io.xconn.echo", invocation_handler)


async def invocation_handler(invocation: Invocation):
    print(f"Received args={invocation.args}, kwargs={invocation.kwargs}, details={invocation.details}")

void exampleRegister(Session session) async {
  var registration = await session.register("io.xconn.echo", invocationHandler);
}

Result invocationHandler(Invocation invocation) {
  return Result(args: invocation.args, kwargs: invocation.kwargs, details: invocation.details);
}
func exampleRegister(_ session: Session) {
    try await session.register(procedure: "io.xconn.echo", endpoint: echoHandler)
}

func echoHandler(_ invocation: Invocation) -> Result {
    return Result(args: invocation.args, kwargs: invocation.kwargs)
}

Synchronous

use xconn::sync::session::Session;
use xconn::sync::types::{Invocation, RegisterRequest, Yield};

fn example_register(session: Session) {
    let register_request = RegisterRequest::new("io.xconn.echo", invocation_handler);
    match session.register(register_request) {
        Ok(response) => println!("{response:?}"),
        Err(e) => println!("{e}"),
    }
}

fn invocation_handler(inv: Invocation) -> Yield {
    Yield::new(inv.args, inv.kwargs)
}

Asynchronous

use xconn::async_::session::Session;
use xconn::async_::types::{Invocation, RegisterRequest, Yield};

async fn example_register(session: Session) {
    let register_request = RegisterRequest::new("io.xconn.echo", invocation_handler);
    match session.register(register_request).await {
        Ok(response) => println!("{response:?}"),
        Err(e) => println!("{e}"),
    }
}

async fn invocation_handler(invocation: Invocation) -> Yield {
    Yield::new(invocation.args, invocation.kwargs)
}

suspend fun exampleRegister(session: Session) {
    session.register("io.xconn.echo", { invocation ->
        Result(args = invocation.args, kwargs = invocation.kwargs)
    }).await()
}
import {Session, Invocation, Result} from "xconn";


async function exampleRegister(session: Session) {
    const onEcho = (invocation: Invocation): Result => {
        return new Result(invocation.args, invocation.kwargs, invocation.details);
    };

    await session.register("io.xconn.echo", onEcho);
}

Call a procedure

func exampleCall(session *xconn.Session) {
callResponse := session.Call("io.xconn.echo").Arg(1).Arg(2).Kwarg("key", "value").Do()
if callResponse.Err != nil {
    log.Fatalf("Failed to call: %v", callResponse.Err)
}
}

Synchronous

from xconn.session import Session

def example_call(session: Session):
    session.call("io.xconn.echo", [1, 2], {"key": "value"})

Asynchronous

from xconn.async_session import AsyncSession

async def example_call(session: AsyncSession):
    await session.call("io.xconn.echo", [1, 2], {"key": "value"})

void exampleCall(Session session) async {
  await session.call("io.xconn.echo", args: [1, 2], kwargs: {"key": "value"});
}
func exampleCall(_ session: Session) {
    try await session.call(
        procedure: "io.xconn.echo",
        args: [1, 2],
        kwargs: ["key": "value"]
    )
}

Synchronous

use xconn::sync::session::Session;
use xconn::sync::types::CallRequest;

fn example_call(session: Session) {
    let call_request = CallRequest::new("io.xconn.echo").arg(1).arg(2).kwarg("key", "value");
    session.call(call_request).unwrap();
}

Asynchronous

use xconn::async_::session::Session;
use xconn::async_::types::CallRequest;

async fn example_call(session: Session) {
    let call_request = CallRequest::new("io.xconn.echo").arg(1).arg(2).kwarg("key", "value");

    session.call(call_request).await.unwrap();
}

suspend fun exampleCall(session: Session) {
    session.call(
        "io.xconn.echo",
        args = listOf(1, 2),
        kwargs = mapOf("key" to "value")
    ).await()
}
import {Session} from "xconn";


async function exampleCall(session: Session) {
    await session.call("io.xconn.echo", {args: [1, 2], kwargs: {"key": "value"}});
}

Authentication

Ticket Authentication

session, err := xconn.ConnectTicket(context.Background(), "ws://localhost:8080/ws", "realm1", "authid", "ticket")
if err != nil {
    log.Fatalf("Failed to connect: %v", err)
}

Synchronous

from xconn.session import Session
from xconn.client import connect_ticket

session: Session = connect_ticket("ws://localhost:8080/ws", "realm1", "authid", "ticket")

Asynchronous

from xconn import run
from xconn.async_session import AsyncSession
from xconn.async_client import connect_ticket

async def connect():
    session: AsyncSession = await connect_ticket("ws://localhost:8080/ws", "realm1", "authid", "ticket")

if __name__ == "__main__":
    run(connect())

import "package:xconn/xconn.dart";

void main() async {
  var session = connectTicket("ws://localhost:8080/ws", "realm1", "authid", "ticket");
}
let authenticator = TicketAuthenticator(authID: "authid", ticket: "ticket")
let client = Client(authenticator: authenticator)
let session = try await client.connect(uri: "ws://localhost:8080/ws", realm: "realm1")

Synchronous

use xconn::sync::client::connect_ticket;

let session = connect_ticket("ws://localhost:8080", "realm1", "authid", "ticket").unwrap_or_else(|e| panic!("{e}"));

Asynchronous

use xconn::async_::client::connect_ticket;

let session = connect_ticket("ws://localhost:8080/ws", "realm1", "authid", "ticket")
    .await
    .unwrap_or_else(|e| panic!("{e}"));

import io.xconn.xconn.connectTicket


val session = connectTicket("ws://localhost:8080/ws", "realm1", "authid", "ticket")
import {connectTicket} from "xconn";


const session = await connectTicket("ws://localhost:8080/ws", "realm1", "authid", "ticket");

Challenge Response Authentication

session, err := xconn.ConnectCRA(context.Background(), "ws://localhost:8080/ws", "realm1", "authid", "secret")
if err != nil {
    log.Fatalf("Failed to connect: %v", err)
}

Synchronous

from xconn.session import Session
from xconn.client import connect_wampcra

session: Session = connect_wampcra("ws://localhost:8080/ws", "realm1", "authid", "secret")

Asynchronous

from xconn import run
from xconn.async_session import AsyncSession
from xconn.async_client import connect_wampcra

async def connect():
    session: AsyncSession = await connect_wampcra("ws://localhost:8080/ws", "realm1", "authid", "secret")

if __name__ == "__main__":
    run(connect())

import "package:xconn/xconn.dart";

void main() async {
  var session = connectCRA("ws://localhost:8080/ws", "realm1", "authid", "secret");
}
let authenticator = CRAAuthenticator(authID: "authid", secret: "secret")
let client = Client(authenticator: authenticator)
let session = try await client.connect(uri: "ws://localhost:8080/ws", realm: "realm1")

Synchronous

use xconn::sync::client::connect_wampcra;

let session = connect_wampcra("ws://localhost:8080", "realm1", "authid", "secret").unwrap_or_else(|e| panic!("{e}"));

Asynchronous

use xconn::async_::client::connect_wampcra;

let session = connect_wampcra("ws://localhost:8080/ws", "realm1", "authid", "secret")
    .await
    .unwrap_or_else(|e| panic!("{e}"));

import io.xconn.xconn.connectCRA


val session = connectCRA("ws://localhost:8080/ws", "realm1", "authid", "secret")
import {connectCRA} from "xconn";


const session = await connectTicket("ws://localhost:8080/ws", "realm1", "authid", "secret");

Cryptosign Authentication

session, err := xconn.ConnectCryptosign(context.Background(), "ws://localhost:8080/ws", "realm1", "authid", "d850fff4ff199875c01d3e652e7205309dba2f053ae813c3d277609150adff13")
if err != nil {
    log.Fatalf("Failed to connect: %v", err)
}

Synchronous

from xconn.session import Session
from xconn.client import connect_cryptosign

session: Session = connect_cryptosign("ws://localhost:8080/ws", "realm1", "authid", "d850fff4ff199875c01d3e652e7205309dba2f053ae813c3d277609150adff13")

Asynchronous

from xconn import run
from xconn.async_session import AsyncSession
from xconn.async_client import connect_cryptosign

async def connect():
    session: AsyncSession = await connect_cryptosign("ws://localhost:8080/ws", "realm1", "authid", "d850fff4ff199875c01d3e652e7205309dba2f053ae813c3d277609150adff13")

if __name__ == "__main__":
    run(connect())

import "package:xconn/xconn.dart";

void main() async {
  var session = connectCryptosign("ws://localhost:8080/ws", "realm1", "authid", "d850fff4ff199875c01d3e652e7205309dba2f053ae813c3d277609150adff13");
}
let authenticator = try CryptoSignAuthenticator(authID: "authid", privateKey: "d850fff4ff199875c01d3e652e7205309dba2f053ae813c3d277609150adff13")
let client = Client(authenticator: authenticator)
let session = try await client.connect(uri: "ws://localhost:8080/ws", realm: "realm1")

Synchronous

use xconn::sync::client::connect_cryptosign;

let session = connect_cryptosign("ws://localhost:8080", "realm1", "authid", "d850fff4ff199875c01d3e652e7205309dba2f053ae813c3d277609150adff13").unwrap_or_else(|e| panic!("{e}"));

Asynchronous

use xconn::async_::client::connect_cryptosign;

let session = connect_cryptosign("ws://localhost:8080/ws", "realm1", "authid", "d850fff4ff199875c01d3e652e7205309dba2f053ae813c3d277609150adff13")
    .await
    .unwrap_or_else(|e| panic!("{e}"));

import io.xconn.xconn.connectCryptosign


val session = connectCryptosign("ws://localhost:8080/ws", "realm1", "authid", "d850fff4ff199875c01d3e652e7205309dba2f053ae813c3d277609150adff13")
import {connectCryptosign} from "xconn";


const session = await connectCryptosign("ws://localhost:8080/ws", "realm1", "authid", "d850fff4ff199875c01d3e652e7205309dba2f053ae813c3d277609150adff13");

Serializers

The library supports multiple serializers for data serialization. You can choose the one that best fits your needs. Here are a few examples

JSON Serializer

client := xconn.Client{SerializerSpec: xconn.JSONSerializerSpec}
session, err := client.Connect(context.Background(), "ws://localhost:8080/ws", "realm1")
if err != nil {
    log.Fatalf("Failed to connect: %v", err)
}

Synchronous

from xconn.session import Session
from xconn import Client, JSONSerializer


client = Client(serializer=JSONSerializer())
session: Session = client.connect("ws://localhost:8080/ws", "realm1")

Asynchronous

from xconn.async_session import AsyncSession
from xconn import AsyncClient, JSONSerializer, run


async def main():
    client = AsyncClient(serializer=JSONSerializer())
    session: AsyncSession = await client.connect("ws://localhost:8080/ws", "realm1")


if __name__ == "__main__":
    run(main())

import "package:xconn/xconn.dart";

void main() async {
  var client = Client(config: ClientConfig(serializer: JSONSerializer()));
  var session = client.connect("ws://localhost:8080/ws", "realm1");
}
let client = Client(serializer: JSONSerializer())
let session = try await client.connect(uri: "ws://localhost:8080/ws", realm: "realm1")

Synchronous

use wampproto::authenticators::anonymous::AnonymousAuthenticator;

use xconn::sync::client::Client;
use xconn::sync::types::JSONSerializerSpec;

fn main() {
    let serializer = Box::new(JSONSerializerSpec {});
    let authenticator = Box::new(AnonymousAuthenticator::new("", Default::default()));
    let client = Client::new(serializer, authenticator);
    let session = client
        .connect("ws://localhost:8080/ws", "realm1")
        .unwrap_or_else(|e| panic!("{e}"));
}

Asynchronous

use wampproto::authenticators::anonymous::AnonymousAuthenticator;

use xconn::async_::client::Client;
use xconn::async_::types::JSONSerializerSpec;

#[tokio::main]
async fn main() {
    let serializer = Box::new(JSONSerializerSpec {});
    let authenticator = Box::new(AnonymousAuthenticator::new("", Default::default()));
    let client = Client::new(serializer, authenticator);
    let session = client
        .connect("ws://localhost:8080/ws", "realm1")
        .await
        .unwrap_or_else(|e| panic!("{e}"));
}

import io.xconn.wampproto.serializers.JSONSerializer
import io.xconn.xconn.Client


val client = Client(serializer = JSONSerializer())
val session = client.connect("ws://localhost:8080/ws", "realm1")
import {Client, JSONSerializer} from "xconn";


async function main() {
    const client = new Client({serializer: new JSONSerializer()});
    const session = await client.connect("ws://localhost:8080/ws", "realm1");
}

CBOR Serializer

client := xconn.Client{SerializerSpec: xconn.CBORSerializerSpec}
session, err := client.Connect(context.Background(), "ws://localhost:8080/ws", "realm1")
if err != nil {
    log.Fatalf("Failed to connect: %v", err)
}

Synchronous

from xconn.session import Session
from xconn import Client, CBORSerializer


client = Client(serializer=CBORSerializer())
session: Session = client.connect("ws://localhost:8080/ws", "realm1")

Asynchronous

from xconn.async_session import AsyncSession
from xconn import AsyncClient, CBORSerializer, run


async def main():
    client = AsyncClient(serializer=CBORSerializer())
    session: AsyncSession = await client.connect("ws://localhost:8080/ws", "realm1")


if __name__ == "__main__":
    run(main())

import "package:xconn/xconn.dart";

void main() async {
  var client = Client(config: ClientConfig(serializer: CBORSerializer()));
  var session = client.connect("ws://localhost:8080/ws", "realm1");
}
let client = Client(serializer: CBORSerializer())
let session = try await client.connect(uri: "ws://localhost:8080/ws", realm: "realm1")

Synchronous

use wampproto::authenticators::anonymous::AnonymousAuthenticator;

use xconn::sync::client::Client;
use xconn::sync::types::CBORSerializerSpec;

fn main() {
    let serializer = Box::new(CBORSerializerSpec {});
    let authenticator = Box::new(AnonymousAuthenticator::new("", Default::default()));
    let client = Client::new(serializer, authenticator);
    let session = client
        .connect("ws://localhost:8080/ws", "realm1")
        .unwrap_or_else(|e| panic!("{e}"));
}

Asynchronous

use wampproto::authenticators::anonymous::AnonymousAuthenticator;

use xconn::async_::client::Client;
use xconn::async_::types::CBORSerializerSpec;

#[tokio::main]
async fn main() {
    let serializer = Box::new(CBORSerializerSpec {});
    let authenticator = Box::new(AnonymousAuthenticator::new("", Default::default()));
    let client = Client::new(serializer, authenticator);
    let session = client
        .connect("ws://localhost:8080/ws", "realm1")
        .await
        .unwrap_or_else(|e| panic!("{e}"));
}

import io.xconn.wampproto.serializers.CBORSerializer
import io.xconn.xconn.Client


val client = Client(serializer = CBORSerializer())
val session = client.connect("ws://localhost:8080/ws", "realm1")
import {Client, CBORSerializer} from "xconn";


async function main() {
    const client = new Client({serializer: new CBORSerializer()});
    const session = await client.connect("ws://localhost:8080/ws", "realm1");
}

MsgPack Serializer

client := xconn.Client{SerializerSpec: xconn.MsgPackSerializerSpec}
session, err := client.Connect(context.Background(), "ws://localhost:8080", "realm1")
if err != nil {
    log.Fatalf("Failed to connect: %v", err)
}

Synchronous

from xconn.session import Session
from xconn import Client, MsgPackSerializer


client = Client(serializer=MsgPackSerializer())
session: Session = client.connect("ws://localhost:8080/ws", "realm1")

Asynchronous

from xconn.async_session import AsyncSession
from xconn import AsyncClient, MsgPackSerializer, run


async def main():
    client = AsyncClient(serializer=MsgPackSerializer())
    session: AsyncSession = await client.connect("ws://localhost:8080/ws", "realm1")


if __name__ == "__main__":
    run(main())

import "package:xconn/xconn.dart";

void main() async {
  var client = Client(config: ClientConfig(serializer: MsgPackSerializer()));
  var session = client.connect("ws://localhost:8080/ws", "realm1");
}
let client = Client(serializer: MsgPackSerializer())
let session = try await client.connect(uri: "ws://localhost:8080/ws", realm: "realm1")

Synchronous

use wampproto::authenticators::anonymous::AnonymousAuthenticator;

use xconn::sync::client::Client;
use xconn::sync::types::MsgPackSerializerSpec;

fn main() {
    let serializer = Box::new(MsgPackSerializerSpec {});
    let authenticator = Box::new(AnonymousAuthenticator::new("", Default::default()));
    let client = Client::new(serializer, authenticator);
    let session = client
        .connect("ws://localhost:8080/ws", "realm1")
        .unwrap_or_else(|e| panic!("{e}"));
}

Asynchronous

use wampproto::authenticators::anonymous::AnonymousAuthenticator;

use xconn::async_::client::Client;
use xconn::async_::types::MsgPackSerializerSpec;

#[tokio::main]
async fn main() {
    let serializer = Box::new(MsgPackSerializerSpec {});
    let authenticator = Box::new(AnonymousAuthenticator::new("", Default::default()));
    let client = Client::new(serializer, authenticator);
    let session = client
        .connect("ws://localhost:8080/ws", "realm1")
        .await
        .unwrap_or_else(|e| panic!("{e}"));
}

import io.xconn.wampproto.serializers.MsgPackSerializer
import io.xconn.xconn.Client


val client = Client(serializer = MsgPackSerializer())
val session = client.connect("ws://localhost:8080/ws", "realm1")
import {Client, MsgPackSerializer} from "xconn";


async function main() {
    const client = new Client({serializer: new MsgPackSerializer()});
    const session = await client.connect("ws://localhost:8080/ws", "realm1");
}

Cap'n Proto Serializer

client := xconn.Client{SerializerSpec: xconn.CapnprotoSplitSerializerSpec}
session, err := client.Connect(context.Background(), "ws://localhost:8080", "realm1")
if err != nil {
    log.Fatalf("Failed to connect: %v", err)
}

Synchronous

from xconn.session import Session
from xconn import Client, CapnProtoSerializer


client = Client(serializer=CapnProtoSerializer())
session: Session = client.connect("ws://localhost:8080/ws", "realm1")

Asynchronous

from xconn.async_session import AsyncSession
from xconn import AsyncClient, CapnProtoSerializer, run


async def main():
    client = AsyncClient(serializer=CapnProtoSerializer())
    session: AsyncSession = await client.connect("ws://localhost:8080/ws", "realm1")


if __name__ == "__main__":
    run(main())