Hi everyone. Has anyone tried to use `Pub/Sub` usi...
# sst
i
Hi everyone. Has anyone tried to use
Pub/Sub
using
aws-amplify
npm package? I did back-end part thankfully to this page https://serverless-stack.com/examples/how-to-use-pub-sub-in-your-serverless-app.html but I can't connect it with
front-end
. Official docs https://docs.amplify.aws/lib/pubsub/getting-started/q/platform/js/ doesn't cover a step how to configure pub/sub on the front-end using
aws-amplify
npm package. It assumes to use
aws cli
t
I just setup a prototype of this without amplify
oh nevermind this is with SNS, was thinking iot pubsub
i
@thdxr is there a way to use it somehow without `amplify`/
aws-amplify
?
t
What I setup was AWS IoT pub/sub and on the frontend I use the paho-mqtt client (it's what amplify uses under the hood)
i
@thdxr Can you point me on any resources where I can find the info how to setup it, please?
t
I had to pretty much glue it together myself, we'll probably release a construct for it. Let me see if I can share something useful. Here's my SST code
Copy code
export function Realtime(ctx: StackContext) {
  const fn = new Function(ctx.stack, "fn", {
    handler: "services/realtime/authorizer.handler",
    permissions: ["iot"],
  })
  const authorizer = new iot.CfnAuthorizer(ctx.stack, "authorizer", {
    status: "ACTIVE",
    authorizerFunctionArn: fn.functionArn,
    signingDisabled: true,
  })

  fn.addPermission("IOTPermission", {
    principal: new ServicePrincipal("<http://iot.amazonaws.com|iot.amazonaws.com>"),
    sourceArn: authorizer.attrArn,
    action: "lambda:InvokeFunction",
  })

  return {
    endpoint:
      ENDPOINTS[ctx.app.stage as keyof typeof ENDPOINTS] || ENDPOINTS.dev,
  }
}
Note I'm using a custom authorizer - this basically can return any IAM policy to grant to whoever is connecting. Unfortunately the IoT endpoints are retreivable in code so I had to hardcode a list of them per aws account - which is what that return type is Then on the frontend:
Copy code
import { Client, Message } from "paho-mqtt"
import { useEffect } from "react"
import { v4 } from "uuid"

const Realtime = new Client(
  `wss://${
    import.meta.env.VITE_REALTIME_ENDPOINT
  }/mqtt?x-amz-customauthorizer-name=authorizer`,
  v4()
)

console.log(import.meta.env)

const onMessage: ((msg: Message) => void)[] = []
Realtime.onMessageArrived = (evt) => {
  onMessage.forEach((cb) => cb(evt))
  console.log(evt)
}
Realtime.onMessageDelivered = console.log
Realtime.onConnectionLost = console.log

Realtime.connect({
  useSSL: true,
  mqttVersion: 4,
  reconnect: true,
  onSuccess: () => {
    Realtime.subscribe("#")
  },
  onFailure: console.log,
})
This example is subscribing to 100% of topics. From here the backend can publish events and the frontend will get it
here's a naive implementation:
Copy code
export const handler = async (evt: any) => {
  return {
    isAuthenticated: true,
    principalId: "asd",
    disconnectAfterInSeconds: 86400,
    refreshAfterInSeconds: 300,
    policyDocuments: [
      {
        Version: "2012-10-17",
        Statement: [
          {
            Action: "iot:*",
            Effect: "Allow",
            Resource: "*",
          },
        ],
      },
    ],
  }
}
k
I am using https://pusher.com/ for now since it is so simple 😂 Dax your solution looks so simple that I might have to switch, any thoughts on IOT pricing ?
t
I never look at AWS pricing lol, I deal with it later
k
I think I pretend to look at the pricing and do the same 😂
I never look at AWS pricing lol, I deal with it later
Considering ^ I am assuming nothing came up yet for IOT so it is good to go 😂
i
@thdxr Could you tell me where all these constructs are imported from?
And...what if I use
web socket
instead of PubSub?
t
this setup goes over websocket, but if you're talking about our WebsocketApi construct you can definitely use that, just has some caveats with broadcasting to a lot of subscribers
Copy code
import { Function, StackContext } from "@serverless-stack/resources"
import { CfnAuthorizer } from "aws-cdk-lib/aws-iot"
import { ServicePrincipal } from "aws-cdk-lib/aws-iam"