chatter

package
v2.2.0+incompatible Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 11, 2020 License: MIT Imports: 7 Imported by: 1

README

Chatter Service

The "chatter" service illustrates the streaming endpoint features in goa v2.

Design

An endpoint becomes a streaming endpoint if any of the following DSLs are used in the Method expression.

  • StreamingPayload - client streams payload to the server
  • StreamingResult - server streams result to the client

When both the above DSLs are defined in a Method expression, the endpoint becomes a bidirectional stream. The syntax for the StreamingPayload and StreamingResult DSLs are similar to the Payload and Result DSLs.

login Endpoint

This is a non-streaming endpoint which authenticates the user using the basic auth scheme and returns a valid JWT token to be sent by the other endpoints.

$ ./chatter_cli chatter login --user "goa" --password "rocks"
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE1MzQxOTg0NjgsIm5iZiI6MTQ0NDQ3ODQwMCwic2NvcGV
zIjpbInN0cmVhbTpyZWFkIiwic3RyZWFtOndyaXRlIl19.frlyMLZeSCSFthtaYe3tZYkg0nMqwREOj-55J6IUxyg"
$ export JWT_TOKEN=`echo $_`
listener Endpoint

This endpoint illustrates a streaming payload. The client sends a payload defined in Payload DSL containing the JWT token. Once auth succeeds, the client streams the payload defined in StreamingPayload DSL to the server. The server patiently listens until the client stops sending the payload.

$ ./chatter_cli chatter listener --token $JWT_TOKEN
Press Ctrl+D to stop chatting.
thanks for listening
you are very patient
summary Endpoint

This endpoint is similar to the listener endpoint. The only difference is the server responds back with a summary of all the messages sent by the client.

$ ./chatter_cli chatter summary --token $JWT_TOKEN
testing 1 2 3
check check check
[
    {
        "Message": "testing 1 2 3",
        "Length": 13,
        "SentAt": "2018-08-14T12:32:26-07:00"
    },
    {
        "Message": "check check check",
        "Length": 17,
        "SentAt": "2018-08-14T12:32:30-07:00"
    }
]
subscribe Endpoint

This endpoint illustrates a streaming result. The client sends a payload defined in the Payload DSL and that contains a JWT token. Once auth succeeds, the server establishes a stream. The sends messages to the client using the stream. The subscription ends when the client goes away or the server shuts down.

$ ./chatter_cli chatter subscribe --token $JWT_TOKEN
# Now send messages to server in a separate `chatter_cli` process by calling
# the `summary`, `listener`, or `echoer` endpoints.
{
    "Message": "hello",
    "Action": "added",
    "AddedAt": "2018-08-14T12:32:30-07:00"
}
history Endpoint

This endpoint illustrates a streaming result with views. The client sends a payload defined in the Payload DSL and that contains a JWT token and an optional "view" parameter. Once auth succeeds, the server sends results to the client using the stream. Each result struct is first projected to the view matching the "view" parameter.

$ ./chatter_cli chatter history --token $JWT_TOKEN --view tiny
{
    "Message": "thanks for listening",
    "Length": null,
    "SentAt": null
}
{
    "Message": "you are very patient",
    "Length": null,
    "SentAt": null
}
{
    "Message": "testing 1 2 3",
    "Length": null,
    "SentAt": null
}
{
    "Message": "check check check",
    "Length": null,
    "SentAt": null
}
echoer Endpoint

This endpoint illustrates a bidirectional streaming. The client sends a payload defined in Payload DSL containing the JWT token. Once auth succeeds, the client and server communicates via the stream until one of them quits. The server simply echoes the client messages.

$ ./chatter_cli chatter echoer --token $JWT_TOKEN
Press Ctrl+D to stop chatting.
say my name
"say my name"
stop repeating me 
"stop repeating me"

Customizing HTTP Websocket Connections

goa v2 uses gorilla websocket underneath to implement streaming via websocket in the HTTP transport layer. By default, goa v2 uses the default Upgrader server side to upgrade HTTP connection to a websocket connection and the DefaultDialer client side to dial a websocket connection.

Developers can use custom Upgrader and Dialer as shown below

// In server main.go

var (
  chatterServer *chattersvcsvr.Server
)
{
  eh := ErrorHandler(logger)

  // my custom websocket Upgrader
  myUpgrader := &websocket.Upgrader{
    ReadBufferSize: 512,
    WriteBufferSize: 512,
  }

  // pass a ConnConfigureFunc type as an argument to apply the connection
  // configurer to all the streaming endpoints
  chatterConfigurer := chattersvcsvr.NewConnConfigurer(myConfigurerFn)
  // or override the connection configurer for a specific streaming endpoint
  chatterConfigurer.SubscribeFn = mySubscriberConfigurerFn

  chatterServer = chattersvcsvr.New(chatterEndpoints, mux, dec, enc, eh, myUpgrader, chatterConfigurer)
}

// In client main.go

var (
  myDialer          *websocket.Dialer
  chatterConfigurer *chattersvcclient.ConnConfigurer
)
{
  chatterConfigurer = chattersvcclient.NewConnConfigurer(myConfigurerFn)
  myDialer = websocket.Dialer{
    ReadBufferSize: 512,
    WriteBufferSize: 512,
  }
}

endpoint, payload, err := cli.ParseEndpoint(
  scheme,
  host,
  doer,
  goahttp.RequestEncoder,
  goahttp.ResponseDecoder,
  debug,
  myDialer,
  chatterConfigurer,
)

Check out the pingPonger defined in cmd/chatter/http.go for how to use ConnConfigureFunc to customize the websocket connection to send periodic pings to the client and cancel the request if the client does not respond with a pong.

Gotchas

  • goa v2 uses websockets to implement streaming in the HTTP transport layer. The websocket protocol has two parts, an opening handshake and the data transfer. The opening handshake always uses a GET request to the server to upgrade the HTTP connection to a websocket connection. Therefore, even though your goa v2 HTTP endpoint in a streaming method defines a verb other than GET, the first HTTP request is always a GET. This could potentially lead to requests to your streaming endpoint get routed to some other endpoint using the GET verb. To avoid this, if your design defines a streaming method, the corresponding HTTP endpoint should always use a GET method. Any other verb will generate a validation error.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrUnauthorized is the error returned by Login when the request credentials
	// are invalid.
	ErrUnauthorized error = chattersvc.Unauthorized("invalid username and password combination")

	// ErrInvalidToken is the error returned when the JWT token is invalid.
	ErrInvalidToken error = chattersvc.Unauthorized("invalid token")

	// ErrInvalidTokenScopes is the error returned when the scopes provided in
	// the JWT token claims are invalid.
	ErrInvalidTokenScopes error = chattersvc.InvalidScopes("invalid scopes in token")

	// Key is the key used in JWT authentication
	Key = []byte("secret")
)

Functions

func NewChatter

func NewChatter(logger *log.Logger) chattersvc.Service

NewChatter returns the chatter service implementation.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL