Go - Websocket.On()

Register a handler for connections, disconnections, or messages for the websocket.

import (
  "fmt"

  "github.com/nitrictech/go-sdk/handler"
  "github.com/nitrictech/go-sdk/nitric"
)

func main() {
  ws, err := nitric.NewWebsocket("public")
  if err != nil {
    return
  }

  ws.On(handler.WebsocketConnect, func(ctx *handler.WebsocketContext, next handler.WebsocketHandler) (*handler.WebsocketContext, error) {
    // handle connections
    return next(ctx)
  })

  ws.On(handler.WebsocketDisconnect, func(ctx *handler.WebsocketContext, next handler.WebsocketHandler) (*handler.WebsocketContext, error) {
    // handle disconnections
    return next(ctx)
  })

  ws.On(handler.WebsocketMessage, func(ctx *handler.WebsocketContext, next handler.WebsocketHandler) (*handler.WebsocketContext, error) {
    // handle messages
    return next(ctx)
  })

  if err := nitric.Run(); err != nil {
    fmt.Println(err)
  }
}

Parameters

  • Name
    eventType
    Required
    Required
    Type
    WebsocketEventType
    Description

    The type of websocket event to listen for. Can be WebsocketConnect, WebsocketDisconnect, or WebsocketMessage.

  • Name
    middleware
    Required
    Required
    Type
    WebsocketMiddleware
    Description

    The middleware function to use as the handler for Websocket events. If you want to compose more than one middleware use handler.ComposeWebsocketMiddleware.

Examples

Register a handler for message events

ws.On(handler.WebsocketMessage, func(ctx *handler.WebsocketContext, next handler.WebsocketHandler) (*handler.WebsocketContext, error) {
  fmt.Printf("New Message from %s: %s\n", ctx.Request.ConnectionID(), ctx.Request.Message())

  return next(ctx)
})

Manage Websocket connections

To store Websocket connections you can use a Nitric collection.

import (
	"context"
	"fmt"

	"github.com/nitrictech/go-sdk/handler"
	"github.com/nitrictech/go-sdk/nitric"
)

func main() {
	ws, err := nitric.NewWebsocket("public")
	if err != nil {
		return
	}

	connections, err := nitric.NewKv("connections").Allow(nitric.KvStoreGet, nitric.KvStoreSet, nitric.KvStoreDelete)
	if err != nil {
		return
	}

	// Register a new connection on connect
	ws.On(handler.WebsocketConnect, func(ctx *handler.WebsocketContext, next handler.WebsocketHandler) (*handler.WebsocketContext, error) {
		err := connections.Set(context.TODO(), ctx.Request.ConnectionID(), map[string]interface{}{
			"connectionId": ctx.Request.ConnectionID(),
		})
		if err != nil {
			return ctx, err
		}

		return next(ctx)
	})

	// Remove a registered connection on disconnect
	ws.On(handler.WebsocketDisconnect, func(ctx *handler.WebsocketContext, next handler.WebsocketHandler) (*handler.WebsocketContext, error) {
		err := connections.Delete(context.TODO(), ctx.Request.ConnectionID())
		if err != nil {
			return ctx, err
		}

		return next(ctx)
	})

	// Broadcast message to all the registered websocket connections
	ws.On(handler.WebsocketMessage, func(ctx *handler.WebsocketContext, next handler.WebsocketHandler) (*handler.WebsocketContext, error) {
		connectionStream, err := connections.Keys(context.TODO())
		if err != nil {
			return ctx, err
		}

		for {
			connectionId, err := connectionStream.Recv()
			if err != nil {
				break // reached the end of the documents
			}

			err = ws.Send(context.TODO(), connectionId, []byte(ctx.Request.Message()))
			if err != nil {
				return ctx, err
			}
		}

		return next(ctx)
	})

	if err := nitric.Run(); err != nil {
		fmt.Println(err)
	}
}

Chain functions as a single method handler

import (
	"fmt"

	"github.com/nitrictech/go-sdk/handler"
	"github.com/nitrictech/go-sdk/nitric"
)

func validateMessage(ctx *handler.WebsocketContext, next handler.WebsocketHandler) (*handler.WebsocketContext, error) {
	// validate that the message does not contain explicit content

	return next(ctx)
}

func handleMessage(ctx *handler.WebsocketContext, next handler.WebsocketHandler) (*handler.WebsocketContext, error) {
	fmt.Printf("New Message from %s: %s\n", ctx.Request.ConnectionID(), ctx.Request.Message())

	return next(ctx)
}

func main() {
	ws, err := nitric.NewWebsocket("public")
	if err != nil {
		return
	}

	ws.On(handler.WebsocketMessage, handler.ComposeWebsocketMiddleware(validateMessage, handleMessage))

	if err := nitric.Run(); err != nil {
		fmt.Println(err)
	}
}