membuat real time update dengan flask dan socketio

Membuat Real Time Update dengan Flask dan SocketIO

Dalam pengembangan aplikasi web, seringkali kita ingin memperbarui konten secara real-time tanpa perlu me-refresh halaman. Untuk mencapai ini, kita dapat menggunakan teknologi seperti Flask dan SocketIO. Flask adalah kerangka kerja Python yang ringan untuk membangun aplikasi web, sementara SocketIO adalah pustaka JavaScript yang memungkinkan komunikasi real-time antara server dan klien melalui WebSocket.

Dalam tutorial ini, kita akan belajar bagaimana membuat aplikasi Flask yang menggunakan SocketIO untuk mengaktifkan real-time update. Tapi sebelum itu, Anda wajib memiliki Python dan PostgreSQL yang sudah terinstall di sistem Anda.

Persiapan

Pertama buat folder projek dengan nama “real-time-flask-socketio”. Selanjutnya buka folder tersebut melalui text editor kesukaan Anda.

Kemudian buka CMD yang mengarah ke dalam folder projek dan buat python virtual environment dengan menjalankan perintah berikut.

python -m venv env

Perintah di atas akan secara otomatis membuat folder bernama .env di mana python environment lokal dibuat terpisah dari folder instalasi python global Anda.

Setelah itu, aktifkan virtual environment yang barusan Anda buat dengan menjalankan perintah berikut.

env\scripts\activate (for windows)
source env/bin/activate (for linux)

Setelah environment di aktifkan, kita bisa langsung menginstal depedensi yang diperlukan seperti di bawah ini.

pip install -r requirements.txt

Real Time Update

Langkah awal yang perlu kita lakukan yaitu membuat file main.py. Kemudian kita import beberapa modules yang dibutuhkan dalam membuat real time update menggunakan flask dan socket io.

from flask import Flask, render_template, request
from flask_socketio import SocketIO
from random import random
from threading import Lock
from datetime import datetime

Berikut penjelasan dari modul yang akan kita gunakan:

  • Flask: Modul ini menyediakan framework Flask untuk membuat aplikasi web menggunakan Python.
  • render_template: Fungsi ini digunakan untuk merender template HTML dalam Flask.
  • request: Memungkinkan kita untuk mengakses data yang dikirim dalam permintaan HTTP di Flask.
  • SocketIO: Modul ini menyediakan ekstensi SocketIO untuk Flask, yang memungkinkan komunikasi real-time antara klien dan server.
  • random: Memungkinkan kita untuk menghasilkan angka acak atau memilih elemen acak dari suatu urutan.
  • Lock: Kelas ini menyediakan mekanisme penguncian sederhana untuk sinkronisasi thread.
  • datetime: Menyediakan kelas-kelas untuk memanipulasi tanggal dan waktu dalam Python.

Selanjutnya, kita akan membuat variabel thread dan thread_lock. Variabel thread digunakan untuk menyimpan referensi ke thread yang akan dijalankan. Variabel thread_lock digunakan untuk mengatur akses ke variabel thread dan memastikan hanya satu thread yang dapat mengaksesnya pada satu waktu. Ini berguna jika ada operasi yang melibatkan manipulasi variabel thread secara bersamaan oleh beberapa thread.

thread = None
thread_lock = Lock()

Dilanjutkan dengan membuat instansi aplikasi flask dan SocketIO serta mengatur konfigurasi SECRET_KEY untuk aplikasi.

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)

Dengan langkah-langkah di atas, Anda telah membuat instansi Flask dan SocketIO, serta mengatur beberapa pengaturan yang diperlukan untuk menjalankan aplikasi Flask-SocketIO. Sekarang, Anda dapat melanjutkan dengan mendefinisikan rute-rute, event handler, dan fungsi lain yang diperlukan dalam aplikasi Flask-SocketIO Anda.

Selanjutnya, kita akan membuat fungsi get_current_datetime() untuk mengembalikan waktu saat ini yang diformat dalam bentuk string dengan format “bulan/hari/tahun jam:menit:detik”.

def get_current_datetime():
    now = datetime.now()
    return now.strftime("%m/%d/%Y %H:%M:%S")

Kemudian kita buat fungsi background_thread() yang digunakan sebagai thread latar belakang untuk mengirimkan pembaruan data sensor ke klien secara periodik setiap 1 menit.

def background_thread():
    while True:
        dummy_sensor_value = round(random() * 100, 3)
        socketio.emit('updateSensorData', {'value': dummy_sensor_value, "date": get_current_datetime()})
        socketio.sleep(60)

Pada kode di bawah, kita akan mengatur rute, event handler, dan menjalankan aplikasi Flask-SocketIO. Aplikasi akan berjalan dan siap menerima permintaan dari klien, serta mengaktifkan komunikasi real-time menggunakan SocketIO.

@app.route('/')
def index():
    return render_template('index.html')

@socketio.on('connect')
def connect():
    global thread
    print('Client connected')

    global thread
    with thread_lock:
        if thread is None:
            thread = socketio.start_background_task(background_thread)

@socketio.on('disconnect')
def disconnect():
    print('Client disconnected',  request.sid)

if __name__ == '__main__':
    socketio.run(app, debug=True)

Membuat Tampilan

Sekarang kita akan membuat tampilan untuk Real Time Update. Langkah pertama yang perlu dilakukan yaitu membuat folder templates dan pada folder tersebut buat file dengan nama index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Membuat Real Time Update dengan Flask dan SocketIO</title>
  </head>
  <body>
    <h1>Real Time Sensor Display</h1>
    <div class="chart-container">
       <canvas id="myChart" width="1000" height="600"></canvas>
    </div>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.0.4/socket.io.js" integrity="sha512-aMGMvNYu8Ue4G+fHa359jcPb1u+ytAF+P2SCb+PxrjCdO3n3ZTxJ30zuH39rimUggmTwmh2u7wvQsDTHESnmfQ==" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.7.1/chart.min.js"></script>
  </body>
</html>

Bagian penting dari HTML ini adalah kita akan menampilkan canvas HTML5 yang digunakan Chart.js untuk menampilkan grafik garis.

Selanjutnya kita tambahkan script berikut di atas tag </body>

<script>
$(document).ready(function () {
  const ctx = document.getElementById("myChart").getContext("2d");

  const myChart = new Chart(ctx, {
    type: "line",
    data: {
      datasets: [{ label: "Temperature",  }],
    },
    options: {
      borderWidth: 3,
      borderColor: ['rgba(255, 99, 132, 1)',],
    },
  });

  function addData(label, data) {
    myChart.data.labels.push(label);
    myChart.data.datasets.forEach((dataset) => {
      dataset.data.push(data);
    });
    myChart.update();
  }

  function removeFirstData() {
    myChart.data.labels.splice(0, 1);
    myChart.data.datasets.forEach((dataset) => {
      dataset.data.shift();
    });
  }

  const MAX_DATA_COUNT = 10;

  //connect to the socket server.
  var socket = io.connect();

  //receive details from server
  socket.on("updateSensorData", function (msg) {
    console.log("Received sensorData :: " + msg.date + " :: " + msg.value);

    // Show only MAX_DATA_COUNT data
    if (myChart.data.labels.length > MAX_DATA_COUNT) {
      removeFirstData();
    }
    addData(msg.date, msg.value);
  });
});
</script>

Disini kita membuat sebuah grafik garis menggunakan Chart.js. Grafik ini akan ditampilkan di elemen dengan ID “myChart” pada halaman HTML Anda.

  const ctx = document.getElementById("myChart").getContext("2d");

  const myChart = new Chart(ctx, {
    type: "line",
    data: {
      datasets: [{ label: "Temperature",  }],
    },
    options: {
      borderWidth: 3,
      borderColor: ['rgba(255, 99, 132, 1)',],
    },
  });

Fungsi ini digunakan untuk enambahkan data baru ke grafik dengan menyediakan label dan nilai data yang sesuai. Grafik akan diperbarui secara otomatis setelah pemanggilan fungsi addData().

  function addData(label, data) {
    myChart.data.labels.push(label);
    myChart.data.datasets.forEach((dataset) => {
      dataset.data.push(data);
    });
    myChart.update();
  }

Fungsi di bawah ini dapat menghapus data pertama dari grafik. Setelah pemanggilan fungsi removeFirstData(), grafik akan diperbarui secara otomatis dengan data yang telah dihapus.

function removeFirstData() {
    myChart.data.labels.splice(0, 1);
    myChart.data.datasets.forEach((dataset) => {
      dataset.data.shift();
    });
}

Code di bawah ini bertujuan agar klien terhubung ke server SocketIO dan menerima pesan dengan event name “updateSensorData”. Setiap kali pesan diterima, data sensor yang diterima akan ditambahkan ke grafik. Jika jumlah data melebihi batas maksimum MAX_DATA_COUNT, data pertama akan dihapus sebelum menambahkan data baru ke grafik.

  const MAX_DATA_COUNT = 10;

  //connect to the socket server.
  var socket = io.connect();

  //receive details from server
  socket.on("updateSensorData", function (msg) {
    console.log("Received sensorData :: " + msg.date + " :: " + msg.value);

    // Show only MAX_DATA_COUNT data
    if (myChart.data.labels.length > MAX_DATA_COUNT) {
      removeFirstData();
    }
    addData(msg.date, msg.value);
  });

Penutup

Kita telah berhasil membuat proyek yang menampilkan data real-time menggunakan Python, Flask, dan SockeIO. Jika ada bagian dari kode yang tidak dimengerti, Anda bisa tuliskan di kolom komentar di bawah ini.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top