Skip to content

Realtime

Reference doc for the `sst.aws.Realtime` component.

The Realtime component lets you publish and subscribe to messages in realtime.

It offers a topic-based messaging network using AWS IoT. Letting you publish and subscribe to messages using a WebSocket in the browser and your server.

Also, provides an SDK to authorize clients, grant permissions to subscribe, and publish to topics.

There is only 1 IoT endpoint per region per AWS account. Messages from all apps and stages are published to the same IoT endpoint. Make sure to prefix the topics by the app and stage name.

Create a realtime endpoint

sst.config.ts
const server = new sst.aws.Realtime("MyServer", {
authorizer: "src/authorizer.handler"
});

Authorize the client

src/authorizer.ts
import { Resource } from "sst/aws";
import { realtime } from "sst/aws/realtime";
export const handler = realtime.authorizer(async (token) => {
// Validate the token
// Return the topics to subscribe and publish
return {
subscribe: [`${Resource.App.name}/${Resource.App.stage}/chat/room1`],
publish: [`${Resource.App.name}/${Resource.App.stage}/chat/room1`],
};
});

Publish and receive messages in your frontend

app/page.tsx
import { Resource } from "sst/aws";
const client = new mqtt.MqttClient();
// Configure with
// - Resource.Realtime.endpoint
// - Resource.Realtime.authorizer
const connection = client.new_connection(config);
// Subscribe messages
connection.on("message", (topic, payload) => {
// Handle the message
});
// Publish messages
connection.publish(topic, payload, mqtt.QoS.AtLeastOnce);

Subscribe messages in your backend

sst.config.ts
server.subscribe("src/subscriber.handler", {
filter: `${$app.name}/${$app.stage}/chat/room1`
});

Publish message from your backend

src/lambda.ts
import { IoTDataPlaneClient, PublishCommand } from "@aws-sdk/client-iot-data-plane";
const data = new IoTDataPlaneClient();
await data.send(
new PublishCommand({
payload: Buffer.from(
JSON.stringify({ message: "Hello world" })
),
topic: `${Resource.App.name}/${Resource.App.stage}/chat/room1`,
})
);

Constructor

new Realtime(name, args, opts?)

Parameters

RealtimeArgs

authorizer

Type Input<string | FunctionArgs>

The Lambda function that’ll be used to authorize the client on connection.

{
authorizer: "src/authorizer.handler"
}

transform?

Type Object

Transform how this subscription creates its underlying resources.

transform.authorizer?

Type AuthorizerArgs | (args: AuthorizerArgs, opts: ComponentResourceOptions, name: string) => void

Transform the IoT authorizer resource.

Properties

authorizer

Type Output<string>

The name of the IoT authorizer.

endpoint

Type Output<string>

The IoT endpoint.

nodes

Type Object

The underlying resources this component creates.

nodes.authHandler

Type Output<Function>

The IoT authorizer function resource.

nodes.authorizer

Type Authorizer

The IoT authorizer resource.

SDK

Use the SDK in your runtime to interact with your infrastructure.


This is accessible through the Resource object in the SDK.

  • authorizer string

    The name of the IoT authorizer.

  • endpoint string

    The IoT endpoint.

The realtime client SDK is available through the following.

src/authorizer.ts
import { realtime } from "sst/aws/realtime";

authorizer

realtime.authorizer(input)

Parameters

Returns IoTCustomAuthorizerHandler

Creates an authorization handler for the Realtime component. It validates the token and grants permissions for the topics the client can subscribe and publish to.

src/authorizer.ts
export const handler = realtime.authorizer(async (token) => {
// Validate the token
console.log(token);
// Return the topics to subscribe and publish
return {
subscribe: ["*"],
publish: ["*"],
};
});

AuthResult

AuthResult.disconnectAfterInSeconds?

Type number

Default 86400

The maximum duration in seconds of the connection to IoT Core.

The minimum value is 300 seconds, and the maximum is 86400 seconds.

AuthResult.policyDocuments?

Type PolicyDocument[]

Any additional IoT Core policy documents to attach to the client.

There’s a maximum of 10 policy documents. Where each document can contain a maximum of 2048 characters.

{
policyDocuments: [
{
Version: "2012-10-17",
Statement: [
{
Action: "iot:Publish",
Effect: "Allow",
Resource: "*"
}
]
}
]
}

AuthResult.principalId?

Type string

The principal ID of the authorized client. This could be a user ID, username, or phone number.

The value must be an alphanumeric string with at least one, and no more than 128, characters and match the regex pattern, ([a-zA-Z0-9]){1,128}.

AuthResult.publish?

Type string[]

The topics the client can publish to.

For example, this publishes to two specific topics.

{
publish: ["chat/room1", "chat/room2"]
}

And to publish to all topics under a given prefix.

{
publish: ["chat/*"]
}

AuthResult.refreshAfterInSeconds?

Type number

The duration in seconds between policy refreshes. After the given duration, IoT Core will invoke the authorization handler function.

The minimum value is 300 seconds, and the maximum value is 86400 seconds.

AuthResult.subscribe?

Type string[]

The topics the client can subscribe to.

For example, this subscribes to two specific topics.

{
subscribe: ["chat/room1", "chat/room2"]
}

And to subscribe to all topics under a given prefix.

{
subscribe: ["chat/*"]
}

Methods

subscribe

subscribe(subscriber, args)

Parameters

Returns Output<RealtimeLambdaSubscriber>

Subscribe to this Realtime server.

sst.config.ts
server.subscribe("src/subscriber.handler", {
filter: `${$app.name}/${$app.stage}/chat/room1`
});

Customize the subscriber function.

sst.config.ts
server.subscribe(
{
handler: "src/subscriber.handler",
timeout: "60 seconds"
},
{
filter: `${$app.name}/${$app.stage}/chat/room1`
}
);

Or pass in the ARN of an existing Lambda function.

sst.config.ts
server.subscribe("arn:aws:lambda:us-east-1:123456789012:function:my-function", {
filter: `${$app.name}/${$app.stage}/chat/room1`
});

RealtimeSubscriberArgs

filter

Type Input<string>

Filter the topics that’ll be processed by the subscriber.

Subscribe to a specific topic.

{
filter: `${$app.name}/${$app.stage}/chat/room1`
}

Subscribe to all topics under a prefix.

{
filter: `${$app.name}/${$app.stage}/chat/#`
}

transform?

Type Object

Transform how this subscription creates its underlying resources.

transform.topicRule?

Type TopicRuleArgs | (args: TopicRuleArgs, opts: ComponentResourceOptions, name: string) => void

Transform the IoT Topic rule resource.