Go client

Create another application, add github.com/wsrpc/wsrpc-go@main, and save the following as main.go. Run it while the Go quick-start server is running.

package main

import (
	"context"
	"fmt"
	"log"
	"time"

	wsrpc "github.com/wsrpc/wsrpc-go"
	"github.com/wsrpc/wsrpc-go/ws"
)

type Value struct {
	Value int `json:"value"`
}
type EchoParams struct {
	Text string `json:"text"`
}
type EchoResult struct {
	Text string `json:"text"`
}

func main() {
	routes := new(wsrpc.Router)
	if err := routes.Handle("double", func(_ context.Context, p Value) (int, error) { return p.Value * 2, nil }); err != nil {
		log.Fatal(err)
	}
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	peer, err := ws.Dial(ctx, "ws://127.0.0.1:8000/ws/", wsrpc.Options{Routes: routes})
	if err != nil {
		log.Fatal(err)
	}
	defer func() { _ = peer.Close(); peer.Wait() }()
	echo, err := peer.Method[EchoParams, EchoResult]("echo").Call(ctx, EchoParams{Text: "Go"})
	if err != nil {
		log.Fatal(err)
	}
	result, err := peer.Call[int](ctx, "callback", Value{Value: 21})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(echo.Text, result)
}

Peer.Call[R] decodes a result into R. To check both arguments and result at compile time, use peer.Method[Params, Result]("method").Call(ctx, params). peer.Remote("counter").Call[int](ctx, "add", params) provides a namespace for dotted calls. The method string still identifies a runtime protocol method; independent servers can return incompatible data, reported as a decoding error.

The dial context covers the handshake. Every call has its own context and can be cancelled without closing the connection. A local timeout stops local waiting, and does not cancel remote application work: the shared protocol has no cancellation message. Close and wait for the peer when the application is done.

Go’s server/client roles are symmetric. A Go client can register callback methods, receive events or binary data, and use the same typed signals as a server peer. Python and TypeScript clients can call Go routes without a protocol adapter.