Angular NGXS and WebSockets with Laravel backend

Myracle
Myracle
Jan 26, 2019 · 3 min read

Hopefully you have already worked with the exciting state management system for Angular 2+ NGXS. I found that there isn’t a lot of content online about NGXS +WebSocket + Laravel. So here I am, I would like to share how to add WebSocket integration for your Angular App if you are using Laravel as backend.

Let’s get started with a simple scheme, which explains how it works in general:

Let’s go deep into details:

  1. Client app establishes WebSocket connection to our NodeJs/Express server with channelName and clientID (random unique string):
connectToSocket() {const currentUser = JSON.parse(localStorage.getItem('currentUser'));const clientId = uuid.v4();this.store.dispatch(new SetClientID(clientId));if (currentUser && currentUser.token) {this.store.dispatch(new ConnectWebSocket({url: `${environment.nodeServerIp}?channelName=private-budget-${this.id}&token=${currentUser.token}&email=${currentUser.username}&clientId=${clientId}`,}),);}}

2. The client sends typical REST requests to Laravel with clientID and channelName in a payload.

Patch request to Laravel REST server

3. Laravel extracts clientId and channelName and fires the Event class, which sends a message to Redis channel

event(new UpdateBudgetEvent($clientId, $budgetId, $budgets));**** UpdateBudgetEvent class ****class UpdateBudgetEvent extends Event implements ShouldBroadcast
{
....
// broadcastOn method will send to Redis all PUBLIC properties
public function broadcastOn()
{
$data['type'] = '[App] SocketUpdateBudget';
$data['data'] = $this->budget;
$this->data = json_encode($data);
return new PrivateChannel('budget-' . $this->budgetId);
}

4. Nodejs application listens to Redis channel and when a message comes, NodeJs sends a message to the relevant client in the right channel

redis.on('pmessage', (pattern, channel, message) => {message = JSON.parse(message);wss.clients.forEach((client) => {// Check channelif (client.channelName == channel) {// Check clientif (client.clientId != message.data.clientId) {client.send(message.data.data);}}

5. NGXS will automatically get this message (from WebSocket frame) and dispatch the action which will adjust your state

// app.actions.ts
export class SocketUpdateBudget {
static readonly type = '[App] SocketUpdateBudget';constructor(public data: any[]) {}}// app.state.ts
@Action(SocketUpdateBudget)
socketUpdateBudget(ctx: StateContext<AppStateModel>,data: SocketUpdateBudget,) {const state = ctx.getState();// DO your logic with state here}

And that’s actually it, pretty straightforward. Hope it any Angular/NGXS developers out there.

Final result:

Demo

If you want to see more you can also play around at myracle.co.

Hope it was useful reading, don’t hesitate if you have questions or comments and don’t forget to 👏 if this article saves some time in your coding path…

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store