Broadcasting in AdonisJS

In this tutorial we’ll build a broadcasting module for AdonisJS which resembles Laravel Broadcasting features (you can even use Laravel Echo). This module will cover up many of the websockets use cases in a simple manner.

It is great for cases where …


This content originally appeared on DEV Community and was authored by Arthur Emanuel

In this tutorial we'll build a broadcasting module for AdonisJS which resembles Laravel Broadcasting features (you can even use Laravel Echo). This module will cover up many of the websockets use cases in a simple manner.

It is great for cases where the clients need to receive data in real-time, but don't need to send data in real-time.

Good use cases are:

  • Chats
  • Live dashboards
  • Sport scores

Bad use cases are:

  • Games
  • Work together platforms

Let's build it!

Scaffolding a new app

Create a new AdonisJS project

$ npm init create-adonis-ts-app broadcasting
$ yarn create adonis-ts-app broadcasting

When prompted which project structure, select web and flag

Configure webpack for compiling frontend assets? true

Setting up our Broadcast service

Our broadcast module will be based in an open-source Pusher compatible server called pWS.

First, we will install it

$ npm i @soketi/pws
$ yarn add @soketi/pws

We can start the server by running

$ npm pws-server start
$ yarn pws-server start

But we need to configure it before running, so we will make a configuration file for it in config/broadcasting.ts

// config/broadcasting.ts
import Env from '@ioc:Adonis/Core/Env'

const broadcastingConfig = {
  port: Env.get('BROADCASTING_PORT', 6001),
  appId: Env.get('BROADCASTING_APP_ID', 'app-id'),
  appKey: Env.get('BROADCASTING_APP_KEY', 'app-key'),
  appSecret: Env.get('BROADCASTING_APP_KEY', 'app-secret'),
}

export default broadcastingConfig

The configs won't get magically loaded into pWS, so we will make a command to start it. To start it we will use execa. So install it using:

$ npm i execa
$ yarn add execa

and create a command with

$ node ace make:command StartPws

The command will look like this:

// commands/StartPws.ts
import { BaseCommand } from '@adonisjs/core/build/standalone'
import execa from 'execa'

export default class StartPws extends BaseCommand {
  public static commandName = 'start:pws'
  public static description = 'Start the pWS server with Adonis Configs'
  public static settings = {
    loadApp: true,
    stayAlive: true,
  }

  public async run() {
    const broadcastingConfig = this.application.config.get('broadcasting')
    const command = `
      PORT=${broadcastingConfig.port}
      DEFAULT_APP_ID=${broadcastingConfig.appId}
      DEFAULT_APP_KEY=${broadcastingConfig.appKey}
      DEFAULT_APP_SECRET=${broadcastingConfig.appSecret}
      yarn pws-server start`
    await execa(command, { shell: true }).stdout?.pipe(process.stdout)
  }
}

After creating the command, we need to regenerate the ace manifest, so it catches our new command, do it by running:

$ node ace generate:manifest

As pWS is a drop-in Pusher replacement, we can interact with it using any Pusher client, and we will do it. Start by installing the node Pusher client:

$ npm i pusher
$ yarn add pusher

Then we will create a service to interact with the pWS server, it can be done as a simple service or as a AdonisJS provider, in this tutorial we will go the service way.

// app/Services/Broadcast.ts
import Pusher from 'pusher'
import broadcastingConfig from 'Config/broadcasting'
import Env from '@ioc:Adonis/Core/Env'

class Broadcast {
  private pusher = new Pusher({
    host: Env.get('HOST', 'localhost'),
    port: broadcastingConfig.port,
    appId: broadcastingConfig.appId,
    key: broadcastingConfig.appKey,
    secret: broadcastingConfig.appSecret,
  })

  public async broadcast(channel: string | string[], event: string, data: any) {
    const response = await this.pusher.trigger(channel, event, data)
    return response
  }
}

export default new Broadcast()

To listen to events in our frontend we can use PusherJS paired with Laravel Echo. Start by installing both:

$ npm i -D laravel-echo pusher-js
$ yarn add -D laravel-echo pusher-js

And setting up them in our frontend:

<!-- resources/views/welcome.edge -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>AdonisJS - A fully featured web framework for Node.js</title>
    @entryPointStyles('app')
    @entryPointScripts('app')
  </head>
  <body>
    <main>
      <div>
        <h1 class="title">It Works!</h1>
        <p class="subtitle">Congratulations, you have just created your first AdonisJS app.</p>

        <form method="POST" action="/message">
          <input name="message" type="text" />
          <button>Send Message</button>
        </form>
      </div>
    </main>
  </body>
</html>

// resources/js/app.js
import '../css/app.css'
import Echo from 'laravel-echo'

window.Pusher = require('pusher-js')
window.Echo = new Echo({
  broadcaster: 'pusher',
  wsHost: 'localhost',
  wsPort: 6001,
  forceTLS: false,
  disableStats: true,
  key: 'app-key',
  namespace: '',
})

window.Echo.channel('messages').listen('message', (e) => {
  alert(JSON.stringify(e))
})

After setting up that, we just need to setup our message route to broadcast a message event:

// start/routes.ts
import Route from '@ioc:Adonis/Core/Route'
import Broadcast from 'App/Services/Broadcast'

Route.get('/', async ({ view }) => {
  return view.render('welcome')
})

Route.post('/message', async ({ request, response }) => {
  const message = request.input('message')
  await Broadcast.broadcast('messages', 'message', { message })
  return response.redirect().back()
})

It's alive!

But it still doesn't works for private or presence channels, we will address that in next tutorial, stay tuned!


This content originally appeared on DEV Community and was authored by Arthur Emanuel


Print Share Comment Cite Upload Translate Updates
APA

Arthur Emanuel | Sciencx (2021-10-05T01:12:16+00:00) Broadcasting in AdonisJS. Retrieved from https://www.scien.cx/2021/10/05/broadcasting-in-adonisjs/

MLA
" » Broadcasting in AdonisJS." Arthur Emanuel | Sciencx - Tuesday October 5, 2021, https://www.scien.cx/2021/10/05/broadcasting-in-adonisjs/
HARVARD
Arthur Emanuel | Sciencx Tuesday October 5, 2021 » Broadcasting in AdonisJS., viewed ,<https://www.scien.cx/2021/10/05/broadcasting-in-adonisjs/>
VANCOUVER
Arthur Emanuel | Sciencx - » Broadcasting in AdonisJS. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/10/05/broadcasting-in-adonisjs/
CHICAGO
" » Broadcasting in AdonisJS." Arthur Emanuel | Sciencx - Accessed . https://www.scien.cx/2021/10/05/broadcasting-in-adonisjs/
IEEE
" » Broadcasting in AdonisJS." Arthur Emanuel | Sciencx [Online]. Available: https://www.scien.cx/2021/10/05/broadcasting-in-adonisjs/. [Accessed: ]
rf:citation
» Broadcasting in AdonisJS | Arthur Emanuel | Sciencx | https://www.scien.cx/2021/10/05/broadcasting-in-adonisjs/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.