Realtime broadcasting with Laravel and NuxtJS (3/4)

A chat application using Laravel Echo server?

If you follow along, you’d know that making a chat application using Echo server is possible but, not quite ideal ’cause it’s not what it’s built for. It’s more of a general purpose socket.io server with some Laravel specific goodies like user authentication for private channel and notification channel scaffolding.

When you look into the Echo server’s “out of the box” event publishing feature, there’re 2 different ways of doing it.

First off, Redis PUBSUB using psubscribe() API

If you want to send an event this way, you need to broadcast(new LaravelEvent) on a Laravel server to publish it to the Redis channel specified in the LaravelEvent. You see it constantly involves 4 hop relays. 1) A Nuxt app calls Laravel API, 2) Laravel API dispatches the broadcast event via a queue, 3) Laravel worker retrieves it, publish it to Redis using Laravel’s default Redis configuration, 4) Redis client on Echo server receives it and Socket.io client on the same server handles the payload accordingly. You get the picture.

Secondly, HTTP call to Echo server

Like the following JS snippet, all it takes is an HTTP call and Socket.io client on Echo server handles it. That’s it. It is way simpler than the previous one as we don’t need the communication layers in the middle. Nice…

  async chat({ commit }, params) {
    const appId = 'bbbbccccddddeeee'
    const authKey = '33334444555566667777888899990000'
    const socketId = this.$echo.socketId()
    const roomId = params.room
    const adapter = this.$axios.create({
      baseURL: `http://localhost:6001`,
      headers: {
        common: {
          Authorization: authKey,
          Accept: 'application/json;charset=UTF-8',
          'Content-Type': 'application/json',
          'X-Socket-ID': socketId
        }
      }
    })

    await adapter.$post(`/apps/${appId}/events`, {
      channel: `private-chat.${roomId}`,
      name: 'App\\Events\\ChatMessageSent',
      data: {
        room: roomId,
        payload: params.payload
      },
      socket_id: socketId
    })
  },

I’m Sold.

Things that you have to go through to make use of MongoDB on AWS isn’t as smooth as you might think. So I’d rather settle down with the following snippet inside of docker-compose.yml within my local Laradock folder to play with DynamoDB this time. Even though I prefer MongoDB over DynamoDB, taking care of any kinda infra-structure myself would be a pain in the ass. The admin panel (https://github.com/aaronshaf/dynamodb-admin) that I’ve already installed on my 🍎Mac seems fine too.

### AWS DynamoDB Local #####################################
    dynamodb-local:
      image: amazon/dynamodb-local
      command: -jar DynamoDBLocal.jar -dbPath /var/opt/dynamodb/data -sharedDb
      volumes:
        - ${DATA_PATH_HOST}/dynamodb/data:/var/opt/dynamodb/data
      ports:
        - "8000:8000"
      networks:
        - backend

Now what?

Hold on, I could completely ditch the Echo or, partially tweak it to get the most out of it. I’ll have to take a close look at how things work in Echo server first. A couple of things that I want to address with it;

  • An efficient chat server preferably built on top of Laravel Echo server
  • All the bells and whistles of modern chat app features
    • user online status
    • previous message history (save/load data)
    • read flag of each message (read cursors?)
    • unread message count
    • user notification hook (if he/she misses it)
    • horizontal scalability

Leave a Reply