Documentation
¶
Index ¶
- type AuthorizationProvider
- type Client
- func (c *Client) Connect(ctx context.Context) error
- func (c *Client) Disconnect() error
- func (c *Client) IsConnected() bool
- func (c *Client) OnEvent(ctx context.Context, topic string, message any, fields map[string]string) error
- func (c *Client) OnSubscribe(ctx context.Context, topic string) error
- func (c *Client) OnUnsubscribe(ctx context.Context, topic string) error
- func (c *Client) PassThrough(msg bus.EventBusMessage) error
- func (c *Client) Publish(ctx context.Context, topic string, payload any) error
- func (c *Client) PublishSync(ctx context.Context, topic string, payload any) error
- func (c *Client) SetSubscriber(subscriber bus.Subscriber)
- func (c *Client) Subscribe(ctx context.Context, topic string) error
- func (c *Client) Unsubscribe(ctx context.Context, topic string) error
- func (c *Client) UnsubscribeAll(ctx context.Context) error
- type ClientBuilder
- func (b *ClientBuilder) Build() (*Client, error)
- func (b *ClientBuilder) IsValid() error
- func (b *ClientBuilder) WithAuthorization(authHeader string) *ClientBuilder
- func (b *ClientBuilder) WithAuthorizationProvider(provider AuthorizationProvider) *ClientBuilder
- func (b *ClientBuilder) WithDialTimeout(timeout time.Duration) *ClientBuilder
- func (b *ClientBuilder) WithHeader(key, value string) *ClientBuilder
- func (b *ClientBuilder) WithHeaders(headers map[string][]string) *ClientBuilder
- func (b *ClientBuilder) WithLogger(logger *zap.Logger) *ClientBuilder
- func (b *ClientBuilder) WithMonitor(monitor bus.ClientMonitor) *ClientBuilder
- func (b *ClientBuilder) WithSubscriber(subscriber bus.Subscriber) *ClientBuilder
- func (b *ClientBuilder) WithURL(url string) *ClientBuilder
- func (b *ClientBuilder) WithWriteChannelSize(size int) *ClientBuilder
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AuthorizationProvider ¶
AuthorizationProvider is a function that returns an authorization header value. It receives a context and should return the authorization value (e.g., "Bearer token123") or an error if authorization cannot be obtained.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client implements the bus.Client interface over a WebSocket connection. It connects to a vinculum WebSocket server and provides pub/sub functionality.
Example ¶
ExampleClient demonstrates basic usage of the WebSocket client.
logger, _ := zap.NewDevelopment()
// Create a subscriber
subscriber := &exampleSubscriber{}
// Create client using fluent builder pattern
client, err := NewClient().
WithURL("ws://localhost:8080/ws").
WithLogger(logger).
WithDialTimeout(10 * time.Second).
WithSubscriber(subscriber).
WithWriteChannelSize(200). // Configure write buffer size
WithAuthorization("Bearer example-token-123"). // Add authorization
Build()
if err != nil {
log.Fatal(err)
}
// Connect to the server
ctx := context.Background()
if err := client.Connect(ctx); err != nil {
log.Fatal(err)
}
defer client.Disconnect()
// Subscribe to topics
if err := client.Subscribe(ctx, "sensor/+/temperature"); err != nil {
log.Fatal(err)
}
if err := client.Subscribe(ctx, "alerts/#"); err != nil {
log.Fatal(err)
}
// Publish some events
client.Publish(ctx, "sensor/room1/temperature", 23.5)
client.Publish(ctx, "sensor/room2/temperature", 24.1)
client.Publish(ctx, "alerts/high-temperature", "Room 2 temperature is high")
// The subscriber will receive these events asynchronously
time.Sleep(100 * time.Millisecond)
Example (AsClient) ¶
ExampleClient_asClient demonstrates using the client as a bus.Client.
logger, _ := zap.NewDevelopment()
// Create a subscriber
subscriber := &exampleSubscriber{}
// Create client
client, err := NewClient().
WithURL("ws://localhost:8080/ws").
WithLogger(logger).
WithSubscriber(subscriber).
Build()
if err != nil {
log.Fatal(err)
}
// Use Client interface methods
var vinculumClient bus.Client = client
// Connect to WebSocket
ctx := context.Background()
if err := vinculumClient.Connect(ctx); err != nil {
log.Fatal(err)
}
defer vinculumClient.Disconnect()
// Now use it like any Client
vinculumClient.Subscribe(ctx, "notifications/#")
vinculumClient.Publish(ctx, "notifications/user/login", map[string]string{
"user_id": "12345",
"action": "login",
})
time.Sleep(100 * time.Millisecond)
Example (WithDynamicAuth) ¶
ExampleClient_withDynamicAuth demonstrates using dynamic authorization.
logger, _ := zap.NewDevelopment()
subscriber := &exampleSubscriber{}
// Create a dynamic authorization provider
authProvider := func(ctx context.Context) (string, error) {
// In a real application, this might:
// - Refresh an expired JWT token
// - Fetch a new OAuth2 access token
// - Read credentials from a secure store
// For this example, we'll simulate getting a fresh token
token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example"
return "Bearer " + token, nil
}
// Create client with dynamic authorization
client, err := NewClient().
WithURL("ws://localhost:8080/ws").
WithLogger(logger).
WithSubscriber(subscriber).
WithAuthorizationProvider(authProvider). // Dynamic auth
Build()
if err != nil {
log.Fatal(err)
}
// Connect - authorization provider will be called during handshake
ctx := context.Background()
if err := client.Connect(ctx); err != nil {
log.Fatal(err)
}
defer client.Disconnect()
// Use the client normally
client.Subscribe(ctx, "secure/data/#")
client.Publish(ctx, "secure/data/update", map[string]string{
"message": "Authenticated message",
})
time.Sleep(100 * time.Millisecond)
Example (WithMonitor) ¶
ExampleClient_withMonitor demonstrates using a client monitor for lifecycle events.
logger, _ := zap.NewDevelopment()
subscriber := &exampleSubscriber{}
// Create a monitor to track client lifecycle events
monitor := &exampleMonitor{logger: logger}
// Create client with monitor
client, err := NewClient().
WithURL("ws://localhost:8080/ws").
WithLogger(logger).
WithSubscriber(subscriber).
WithMonitor(monitor). // Add lifecycle monitoring
Build()
if err != nil {
log.Fatal(err)
}
// Connect - monitor will receive OnConnect event
ctx := context.Background()
if err := client.Connect(ctx); err != nil {
log.Fatal(err)
}
// Subscribe - monitor will receive OnSubscribe events
client.Subscribe(ctx, "events/#")
client.Subscribe(ctx, "alerts/+")
// Publish some events
client.Publish(ctx, "events/user/login", "user123")
// Unsubscribe - monitor will receive OnUnsubscribe event
client.Unsubscribe(ctx, "alerts/+")
// Disconnect - monitor will receive OnDisconnect event with nil error (graceful)
client.Disconnect()
time.Sleep(100 * time.Millisecond)
func (*Client) Connect ¶
Connect establishes the WebSocket connection and starts message processing.
func (*Client) Disconnect ¶
Disconnect closes the WebSocket connection and stops message processing.
func (*Client) IsConnected ¶ added in v0.14.0
IsConnected reports whether the client currently holds a live WebSocket connection: Connect has succeeded and neither Disconnect nor a read/write error has torn it down.
It is a snapshot, not a guarantee — the connection may drop between this call and the next Publish — which is what makes it useful for a health probe and useless as a precondition. Code that wants to publish should publish and handle the error.
It is deliberately stricter than the check the operational methods make: both the started flag and the connection itself must be present, so the brief window inside cleanup where the socket is already closed reads as disconnected rather than connected.
func (*Client) OnEvent ¶
func (c *Client) OnEvent(ctx context.Context, topic string, message any, fields map[string]string) error
OnEvent implements Subscriber.OnEvent
func (*Client) OnSubscribe ¶
OnSubscribe implements Subscriber.OnSubscribe
func (*Client) OnUnsubscribe ¶
OnUnsubscribe implements Subscriber.OnUnsubscribe
func (*Client) PassThrough ¶
func (c *Client) PassThrough(msg bus.EventBusMessage) error
PassThrough implements Subscriber.PassThrough
func (*Client) PublishSync ¶
PublishSync implements Client.PublishSync - same as Publish for WebSocket client
func (*Client) SetSubscriber ¶ added in v0.9.1
func (c *Client) SetSubscriber(subscriber bus.Subscriber)
func (*Client) Unsubscribe ¶
Unsubscribe implements Client.Unsubscribe
type ClientBuilder ¶
type ClientBuilder struct {
// contains filtered or unexported fields
}
ClientBuilder provides a fluent interface for building WebSocket clients.
func (*ClientBuilder) Build ¶
func (b *ClientBuilder) Build() (*Client, error)
Build creates and returns a new WebSocket client with the configured options.
func (*ClientBuilder) IsValid ¶
func (b *ClientBuilder) IsValid() error
IsValid checks that all required configuration is present.
func (*ClientBuilder) WithAuthorization ¶
func (b *ClientBuilder) WithAuthorization(authHeader string) *ClientBuilder
WithAuthorization sets a static Authorization header value. This will be sent with the WebSocket handshake request. Example: WithAuthorization("Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...")
func (*ClientBuilder) WithAuthorizationProvider ¶
func (b *ClientBuilder) WithAuthorizationProvider(provider AuthorizationProvider) *ClientBuilder
WithAuthorizationProvider sets an authorization provider function. This function will be called during connection to obtain the authorization header.
func (*ClientBuilder) WithDialTimeout ¶
func (b *ClientBuilder) WithDialTimeout(timeout time.Duration) *ClientBuilder
WithDialTimeout sets the timeout for establishing the WebSocket connection.
func (*ClientBuilder) WithHeader ¶
func (b *ClientBuilder) WithHeader(key, value string) *ClientBuilder
WithHeader sets a single HTTP header for the WebSocket handshake. This is a convenience method for setting individual headers. Example: WithHeader("X-API-Key", "key123")
func (*ClientBuilder) WithHeaders ¶
func (b *ClientBuilder) WithHeaders(headers map[string][]string) *ClientBuilder
WithHeaders sets custom HTTP headers for the WebSocket handshake. These headers will be sent along with the WebSocket upgrade request. Note: This will override any existing headers. Use multiple calls to add headers incrementally. Example: WithHeaders(map[string][]string{"X-API-Key": {"key123"}, "User-Agent": {"MyApp/1.0"}})
func (*ClientBuilder) WithLogger ¶
func (b *ClientBuilder) WithLogger(logger *zap.Logger) *ClientBuilder
WithLogger sets the logger for the client.
func (*ClientBuilder) WithMonitor ¶
func (b *ClientBuilder) WithMonitor(monitor bus.ClientMonitor) *ClientBuilder
WithMonitor sets an optional monitor that will receive client lifecycle events. The monitor will be called for connect, disconnect, subscribe, unsubscribe, and unsubscribe all events.
func (*ClientBuilder) WithSubscriber ¶
func (b *ClientBuilder) WithSubscriber(subscriber bus.Subscriber) *ClientBuilder
WithSubscriber sets the subscriber that will receive events from the client.
func (*ClientBuilder) WithURL ¶
func (b *ClientBuilder) WithURL(url string) *ClientBuilder
WithURL sets the WebSocket URL to connect to.
func (*ClientBuilder) WithWriteChannelSize ¶
func (b *ClientBuilder) WithWriteChannelSize(size int) *ClientBuilder
WithWriteChannelSize sets the buffer size for the internal write channel. A larger buffer allows more messages to be queued for writing, which can improve performance under high load but uses more memory. Default is 100.