vincent15000's avatar

crond vs other solutions to send an event each second to a websocket ?

Hello,

I have a problem with a scheduled task via crond.

In a Laravel / VueJS application, I need to send each second an event to the websocket to confirm that the websocket connexion is alive.

But there is problem : I receive an event during perhaps something like 1 minute and then for some seconds or sometimes 1 or 2 minutes, I don't receive any event anymore, and then suddenly I receive one again some events.

I have checked, the websocket connexion is alive, it's sure because I continue receiving other events via the websocket.

So I think that the problem is related to crond, but I'm not sure.

What do you suggest me to check to find what happens ?

And perhaps there is another way to send an event each second ? In JS, there is the setInterval() function, but there isn't any equivalent for PHP, but there are perhaps other solutions ? And I need to do that in PHP.

Thanks a lot for your help.

V

0 likes
2 replies
LaryAI's avatar
Level 58

To address your issue of sending an event every second to a WebSocket in a Laravel/VueJS application, relying on crond might not be the best approach due to its inherent limitations with precise timing and potential delays. Instead, you can leverage a combination of Laravel's task scheduling and a more real-time approach using JavaScript on the client side.

Here’s a more reliable solution:

Server-Side (Laravel)

  1. WebSocket Server: Ensure you have a WebSocket server set up. You can use packages like beyondcode/laravel-websockets to handle WebSocket connections in Laravel.

  2. Broadcasting Events: Use Laravel's broadcasting feature to send events to the WebSocket.

Client-Side (VueJS)

  1. WebSocket Connection: Establish a WebSocket connection in your VueJS application.

  2. Heartbeat Mechanism: Use JavaScript's setInterval() to send a heartbeat message every second to the server.

Example Implementation

Laravel WebSocket Event

First, create an event in Laravel that will be broadcasted:

// app/Events/HeartbeatEvent.php
namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class HeartbeatEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public function __construct()
    {
        //
    }

    public function broadcastOn()
    {
        return new Channel('heartbeat');
    }
}

VueJS WebSocket Client

In your VueJS component, establish a WebSocket connection and use setInterval() to send a heartbeat message every second:

<template>
  <div>
    <!-- Your component template -->
  </div>
</template>

<script>
export default {
  data() {
    return {
      socket: null,
    };
  },
  mounted() {
    this.connectWebSocket();
  },
  methods: {
    connectWebSocket() {
      this.socket = new WebSocket('ws://your-websocket-server-url');

      this.socket.onopen = () => {
        console.log('WebSocket connection established');
        this.startHeartbeat();
      };

      this.socket.onmessage = (event) => {
        console.log('Message from server:', event.data);
      };

      this.socket.onclose = () => {
        console.log('WebSocket connection closed');
        // Optionally, you can try to reconnect
      };
    },
    startHeartbeat() {
      setInterval(() => {
        if (this.socket.readyState === WebSocket.OPEN) {
          this.socket.send(JSON.stringify({ type: 'heartbeat' }));
        }
      }, 1000);
    },
  },
};
</script>

Explanation

  1. Laravel Event: The HeartbeatEvent is a simple event that will be broadcasted on the heartbeat channel.

  2. VueJS WebSocket Client: The VueJS component establishes a WebSocket connection to the server. Once the connection is open, it starts sending a heartbeat message every second using setInterval().

This approach ensures that the heartbeat messages are sent precisely every second without relying on crond, which is not designed for such high-frequency tasks. Additionally, it leverages the real-time capabilities of WebSockets, providing a more robust and reliable solution.

vincent15000's avatar

In the AI response, I don't understand why I would need to create an event in the backend.

Can someone help me understand ?

But I'm quite sure it's not necessary. A simple setInterval() to send a request (ping) to the backend and the backend triggers an event to the front (pong).

Please or to participate in this conversation.