Arsitektur aplikasi chat real-time Next.js dan WebSocket

Aplikasi Chat Real-time Next.js: Bangun dengan WebSocket & Material-UI

Panduan lengkap membangun aplikasi chat real-time menggunakan Next.js, WebSocket (Socket.io), dan Material-UI (MUI) untuk performa optimal dan UI modern.

Pendahuluan

Di era digital yang serba cepat,Β aplikasi chat real-time Next.jsΒ menjadi solusi populer untuk komunikasi instan. Artikel ini membagikan pengalaman praktis membangun aplikasi tersebut menggunakan Next.js, WebSocket (Socket.io), dan Material-UI.

Implementasi Server WebSocket

Pada file server.js, saya membuat server WebSocket yang terintegrasi dengan Next.js:

const { createServer } = require("http");
const next = require("next");
const { Server } = require("socket.io");

const dev = process.env.NODE_ENV !== "production";
const app = next({ dev });
const handle = app.getRequestHandler();

app.prepare().then(() => {
  const server = createServer((req, res) => {
    handle(req, res);
  });

  const io = new Server(server);
  const channelIntervals = new Map(); // Simpan interval per channel

  io.on("connection", (socket) => {
    console.log("🟒 User connected:", socket.id);

    socket.on("joinChannel", (channelId) => {
      if (!channelId) return;

      console.log(`User ${socket.id} joined channel: ${channelId}`);
      socket.join(channelId);

      // Fetch pesan dari Discord API
      const fetchMessages = async () => {
        try {
          const response = await fetch(
            `https://discord.com/api/v10/channels/${channelId}/messages?limit=10`,
            {
              method: "GET",
              headers: {
                Authorization: `Bot ${process.env.DISCORD_BOT_TOKEN}`,
              },
            }
          );

          if (!response.ok) throw new Error("Gagal mengambil pesan");
          const messages = await response.json();
          io.to(channelId).emit("messages", messages);
        } catch (error) {
          console.error(`❌ Error fetching messages for ${channelId}:`, error);
        }
      };

      // Hentikan interval lama jika sudah ada
      if (channelIntervals.has(channelId)) {
        clearInterval(channelIntervals.get(channelId));
      }

      // Mulai polling tiap 5 detik
      fetchMessages();
      const interval = setInterval(fetchMessages, 5000);
      channelIntervals.set(channelId, interval);

      // Cleanup saat disconnect
      socket.on("disconnect", () => {
        console.log("πŸ”΄ User disconnected:", socket.id);
        clearInterval(interval);
      });

      socket.on("leaveChannel", () => {
        console.log(`User ${socket.id} left channel: ${channelId}`);
        clearInterval(interval);
        channelIntervals.delete(channelId);
        socket.leave(channelId);
      });
    });
  });

  server.listen(3000, () => {
    console.log("Server is running on http://localhost:3000");
  });
});

Beberapa poin penting dalam implementasi server:

  1. Integrasi dengan Next.js: Server HTTP dibuat bersama dengan handler Next.js
  2. Manajemen Room: Setiap channel chat dibuat sebagai room terpisah
  3. Polling Otomatis: Sistem melakukan polling otomatis ke Discord API setiap 5 detik
  4. Cleanup Resources: Interval dan koneksi dibersihkan saat user disconnect

Implementasi Client dengan Material-UI

Pada komponen ChatContent, saya membuat antarmuka pengguna yang kaya fitur dengan Material-UI:

const ChatContent = ({ ticket }) => {
  const theme = useTheme();
  const isMobile = useMediaQuery(theme.breakpoints.down('md'));
  const { userData } = useUser();

  // Refs dan state management
  const bottomRef = useRef(null);
  const socketRef = useRef(null);
  const [messages, setMessages] = useState([]);
  const [message, setMessage] = useState('');
  const [file, setFile] = useState(null);
  const [loadingMessages, setLoadingMessages] = useState(false);
  const [sendingMessage, setSendingMessage] = useState(false);
  const [error, setError] = useState(null);

  // Setup WebSocket connection
  const setupSocket = () => {
    if (!ticket?.discordChannelId) return;

    if (socketRef.current) {
      socketRef.current.disconnect();
    }

    socketRef.current = io();
    socketRef.current.emit('joinChannel', ticket.discordChannelId);

    socketRef.current.on('messages', (newMessages) => {
      const sortedMessages = [...newMessages].sort((a, b) => {
        return new Date(a.timestamp) - new Date(b.timestamp);
      });

      const formattedMessages = sortedMessages.map(msg => ({
        ...msg,
        timestamp: msg.timestamp ? new Date(msg.timestamp) : new Date()
      }));

      setMessages(formattedMessages);
    });

    socketRef.current.on('connect_error', (err) => {
      console.error('Socket connection error:', err);
      setError('Realtime connection failed. Messages may not update automatically.');
    });
  };

  // ... (fungsi-fungsi lainnya)
};

Fitur Unggulan Implementasi

1. Real-time Message Updates

Dengan WebSocket, pesan muncul secara real-time tanpa perlu refresh halaman. Setiap kali ada pesan baru di channel, semua anggota channel akan menerima update secara otomatis.

2. UI Responsif dengan Material-UI

Saya memanfaatkan berbagai komponen MUI untuk menciptakan antarmuka yang menarik:

<MainCard
  content={false}
  sx={{
    height: '100%',
    bgcolor: theme.palette.mode === ThemeMode.DARK ? 'dark.main' : 'grey.50',
    pt: 2,
    pl: isMobile ? 0 : 2,
    borderRadius: '0 12px 12px 0',
    transition: theme.transitions.create('width', {
      easing: theme.transitions.easing.easeOut,
      duration: theme.transitions.duration.shorter + 200
    })
  }}
>

3. Emoji Picker yang Interaktif

Integrasi emoji picker dengan animasi yang halus:

<EmojiPicker
  onEmojiClick={(emojiData) => {
    setMessage(message + emojiData.emoji);
    setEmojiPickerOpen(false);
  }}
  defaultSkinTone={SkinTones.DARK}
  autoFocusSearch={false}
/>

4. Upload File dengan Preview

Sistem mendukung upload file dengan validasi:

const handleFileChange = (e) => {
  const selectedFile = e.target.files[0];
  if (!selectedFile) return;

  // Validasi ukuran file (maksimal 5MB)
  const MAX_FILE_SIZE = 5 * 1024 * 1024;
  if (selectedFile.size > MAX_FILE_SIZE) {
    setError('File size too large (max 5MB allowed)');
    return;
  }

  // Validasi tipe file
  const validTypes = [
    'image/jpeg',
    'image/png',
    'image/gif',
    'application/pdf',
    'text/plain',
    'application/msword'
  ];

  if (!validTypes.includes(selectedFile.type)) {
    setError('Only images (JPEG, PNG, GIF), PDF, and text files are allowed');
    return;
  }

  setFile(selectedFile);
  setError(null);
};

5. Auto-scroll ke Pesan Terbaru

Pengalaman pengguna ditingkatkan dengan auto-scroll otomatis:

useEffect(() => {
  bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
}, [messages]);

Hasil

Implementasi WebSocket dengan Next.js dan Material-UI memberikan pengalaman real-time yang mulus dengan antarmuka yang modern.

Beberapa poin kunci yang berhasil saya terapkan:

  1. Integrasi yang baik antara Next.js API routes dengan WebSocket server
  2. Manajemen state yang efisien untuk data real-time
  3. Antarmuka pengguna yang responsif dan kaya fitur dengan Material-UI
  4. Mekanisme fallback dan error handling yang robust

Dengan pendekatan ini, aplikasi chat menjadi lebih interaktif dan menyenangkan untuk digunakan.


Butuh Bantuan Profesional? Tavern Studio Siap Membantu!

Membangun project Next.js membutuhkan keahlian teknis dan pengalaman. Jika Anda ingin:
πŸš€ Website bisnis yang cepat dan SEO-friendly
🎨 Desain modern dengan Tailwind CSS
πŸ”§ Integrasi API & database
πŸ“ˆ Optimasi performa dan keamanan

Tavern Studio siap menjadi mitra IT Anda! Kami menyediakan jasa pengembangan web, mobile, dan sistem berbasis Next.js dengan kualitas terbaik.

Kenapa Memilih Tavern Studio?

βœ” Tim developer berpengalaman
βœ” Solusi tailor-made sesuai kebutuhan bisnis
βœ” Dukungan purna jual yang responsif
βœ” Harga kompetitif dengan hasil maksimal

Hubungi Kami Sekarang!

πŸ“§ Email: ta***********@*****ok.com
πŸ“ž WhatsApp: +62 857-6621-8870

Jangan ragu untuk berkonsultasi gratis! Kami siap membantu mewujudkan project Next.js impian Anda. πŸš€


Dengan Next.js dan dukungan dari Tavern Studio, website Anda akan memiliki performa tinggi, tampilan elegan, dan mudah dikelola. Segera mulai project Anda hari ini! πŸŽ‰