Brazil's biggest MU Online portal — since 2003
Tutorial Advanced Infrastructure

How to build a launcher with push notifications for your MU Online server

Build your own launcher for your MU Online server with a file update system and push notifications, alerting players in real time about events, server outages, and new versions.

RO Rodrigo · Updated on Mar 25, 2017 · ⏱ 17 min read
Quick answer

A launcher is the first program a player opens before even seeing the MU Online login screen, which makes it an underused communication channel on most private servers. Beyond its basic function of checking and downloading client file updates, a modern launcher can keep a persistent connection to th

A launcher is the first program a player opens before even seeing the MU Online login screen, which makes it an underused communication channel on most private servers. Beyond its basic function of checking and downloading client file updates, a modern launcher can keep a persistent connection to the server and display real-time push notifications — warning about events about to start, unexpected server outages, or the release of a new season. This tutorial builds such a launcher with Electron, covering everything from file integrity checks to a WebSocket-based notification system.

General launcher architecture

A complete launcher has three components working together:

ComponentResponsibility
File checkerCompares the local client version with the version published on the server
UpdaterDownloads and applies new or changed files
Notification clientMaintains a connection to the notification server and displays real-time alerts

This tutorial focuses mainly on the third component, assuming the launcher already has (or will have) the first two basic functions implemented.

Prerequisites

  • An existing launcher based on Electron, or willingness to build one from scratch with Node.js + Electron.
  • A separate Node.js server (can run on the same VPS as the website) for the notifications backend.
  • An authenticated admin panel, from where the team will trigger notifications.
  • A valid SSL certificate on the domain used by the notifications backend (secure WebSocket, wss://).

Step 1 — Structure the notifications backend

Create a dedicated Node.js service, separate from the main website application, responsible for keeping open launchers' WebSocket connections and broadcasting messages:

mkdir mu-notify-server && cd mu-notify-server
npm init -y
npm install ws express jsonwebtoken dotenv
// server.js
const { WebSocketServer } = require('ws');
const express = require('express');
const jwt = require('jsonwebtoken');
require('dotenv').config();

const app = express();
app.use(express.json());

const clients = new Set();

const wss = new WebSocketServer({ port: 8081 });
wss.on('connection', (ws) => {
  clients.add(ws);
  ws.on('close', () => clients.delete(ws));
});

// Authenticated endpoint used by the admin panel to trigger notifications
app.post('/broadcast', (req, res) => {
  const auth = req.headers.authorization?.split(' ')[1];
  try {
    jwt.verify(auth, process.env.ADMIN_JWT_SECRET);
  } catch {
    return res.status(401).json({ error: 'unauthorized' });
  }
  const payload = JSON.stringify(req.body);
  clients.forEach(ws => ws.readyState === 1 && ws.send(payload));
  res.json({ sent: clients.size });
});

app.listen(3001, () => console.log('Broadcast API on port 3001'));

Step 2 — Authenticate the admin panel

The /broadcast endpoint should never be accessible without authentication — otherwise anyone could send fake notifications to every player, a clear phishing vector. Generate a long-lived JWT token exclusively for the admin team, store it securely in the panel, and validate it on every call to the endpoint.

Step 3 — Connect the launcher to the WebSocket

In the Electron main process, open the connection as soon as the launcher starts and keep automatic reconnection in case of a drop:

// main.js (Electron main process)
const WebSocket = require('ws');
const { Notification } = require('electron');

function connectNotifications() {
  const ws = new WebSocket('wss://notify.yourserver.com');

  ws.on('message', (data) => {
    const msg = JSON.parse(data);
    new Notification({
      title: msg.titulo || 'Server notice',
      body: msg.corpo,
      icon: 'assets/icon.png'
    }).show();
  });

  ws.on('close', () => {
    setTimeout(connectNotifications, 5000); // tries to reconnect in 5s
  });

  ws.on('error', () => ws.close());
}

connectNotifications();

Step 4 — Display native operating system notifications

Electron's Notification module uses the native notification system of Windows (toast) or macOS, so the player receives the alert even with the launcher minimized in the system tray, as long as the process keeps running in the background.

Step 5 — Categorize notification types

Define categories in the payload sent by the backend, allowing the launcher to handle each type differently (icon, sound, priority):

CategoryExample useVisual priority
evento"Invasion starts in 10 minutes"High, with sound
manutencao"Server will enter maintenance at 10 PM"High, persistent
queda"Server went down, the team is already checking"Critical, sound + highlight
novidade"New season released, check out the changes"Normal, no sound

Step 6 — Build the notification trigger panel

In the admin panel (the same one used to manage accounts and rankings), add a simple form that sends the category, title, and message body to the /broadcast endpoint. Restrict this form to accounts with admin or senior moderator roles — triggering mass notifications should have the same level of access control as any sensitive administrative action.

Step 7 — Automatically detect server outages

Complementing manual triggering, set up a periodic check (every 1-2 minutes) that tests the connection to the ConnectServer/GameServer. If the check fails for two consecutive checks (avoiding a false positive from momentary instability), automatically fire a queda category notification to all connected launchers, without relying on an administrator being available to notice and manually warn players.

Step 8 — Test reconnection and resilience

  1. Force-close the notifications backend with the launcher open and confirm it automatically tries to reconnect.
  2. Send a test notification of each category and confirm it displays correctly on the operating system.
  3. Test the launcher minimized in the tray and confirm the native notification still appears.
  4. Simulate a GameServer outage and confirm the automatic detection fires the correct notification.

Common errors and fixes

SymptomLikely causeFix
Launcher doesn't receive notificationsInvalid SSL certificate on wss://Renew the certificate and validate the WebSocket URL
Anyone can trigger a notification/broadcast endpoint without authenticationRequire a valid JWT from an admin account
Notification doesn't appear with launcher minimizedBackground process terminated by the systemConfigure the launcher to keep running in the tray
False server outage alarmSingle check with no confirmationRequire two consecutive failures before notifying
Reconnection creates multiple duplicate connectionsNo single-connection control per clientClose the previous connection before opening a new one

Launch checklist

  • Notifications backend running with secure WebSocket (wss://).
  • Broadcast endpoint protected by admin JWT authentication.
  • Launcher connecting automatically and reconnecting after a drop.
  • Native operating system notifications tested on Windows.
  • Notification categories defined and visually differentiated.
  • Admin trigger panel restricted to authorized roles.
  • Automatic server outage detection configured and tested.

With the launcher notifying players in real time, the next step is to integrate this channel with the rest of the communication ecosystem — connecting the same notification backend to the Discord bot and the events panel of the MU Online server, centralizing alerts in a single trigger point.

Frequently asked questions

Do I need to rewrite the launcher from scratch, or can I add push notifications to an existing one?

It depends on the current launcher's architecture. If it's already based on Electron or has a background process capable of maintaining a network connection, you can add a notifications module without rewriting the whole launcher. Very old launchers built in Delphi/VB may require more adaptation or even a partial rewrite.

Do push notifications work with the launcher closed?

It depends on the implementation. Operating system notifications (Windows toast) require at least one background process of the launcher to be running to receive them. A lighter alternative is to run only a minimal service that listens to the notification server and launches the full launcher when needed.

How do I prevent the notification system from being used to send spam or phishing?

Restrict sending notifications to an authenticated admin panel, never exposed publicly without login, and always sign/validate the message origin on the client side before displaying any notification, preventing a fake notification server from being injected into the launcher some other way.

What technology should I use for the notification server: WebSocket or HTTP polling?

WebSocket is more efficient for real-time notifications, since it keeps a connection open and avoids repeated requests. HTTP polling is simpler to implement and works well for low notification volumes (a few per hour), but generates more unnecessary traffic at scale.

Are the launcher's file update system and the push notification system the same thing?

No, but they complement each other. The file update system ensures the player's client has the correct version installed; push notifications alert the player about events and changes in real time, regardless of whether a file update is pending.

RO
Founder & editor-in-chief

Rodrigo has run ViciadosMU since the portal's early days. A specialist in MU Online server creation and administration, game history and the evolution of the seasons — he wrote much of the archive before 2024.

Keep reading

Related articles