Skip to content

Latest commit

 

History

History
266 lines (201 loc) · 9.63 KB

File metadata and controls

266 lines (201 loc) · 9.63 KB

MRC Chat

MRC (Multi Relay Chat) is a real-time, multi-BBS chat network that connects users across different bulletin board systems. BinktermPHP includes a WebDoor-based MRC client that lets logged-in users join rooms and chat with users on other connected BBSes.

This feature is experimental. Protocol behaviour, configuration format, and database schema may change in future releases.

How It Works

MRC uses a persistent TCP connection from your BBS to a central MRC relay server. A background daemon (scripts/mrc_daemon.php) maintains that connection. When a user opens the MRC WebDoor in their browser, they interact with the chat through HTTP polling — the browser polls the BinktermPHP API every two seconds for new messages, and the daemon forwards outbound messages to the MRC network.

Browser ←→ BinktermPHP API ←→ mrc_daemon ←→ MRC server ←→ other BBSes

Prerequisites

  • PHP 8.x with the openssl extension (for SSL connections)
  • PostgreSQL
  • The MRC WebDoor enabled in Admin → WebDoors

MRC Servers

Server Version Protocol Environment FQDN Port Security
1.3.20 1.3 Production mrc.bottomlessabyss.net 5000 Plain
1.3.20 1.3 Production mrc.bottomlessabyss.net 5001 SSL
1.3.21-dev 1.3 Testing mrc.bottomlessabyss.net 50000 Plain
1.3.21-dev 1.3 Testing mrc.bottomlessabyss.net 50001 SSL

BinktermPHP ships configured for the testing server (port 50001, SSL) by default. To connect to the production server where most activity happens, update config/mrc.json or use Admin → MRC to set the port to 5000 (plain) or 5001 (SSL).

Setup

1. Configure MRC

Configuration is stored in config/mrc.json. The file is created automatically with defaults on first use. Edit it directly or use Admin → MRC to configure through the web interface.

Minimum required settings:

{
    "enabled": true,
    "server": {
        "host": "mrc.bottomlessabyss.net",
        "port": 5000,
        "use_ssl": false
    },
    "bbs": {
        "name": "My BBS",
        "sysop": "Sysop"
    }
}

Full configuration reference:

{
    "enabled": true,
    "server": {
        "host": "mrc.bottomlessabyss.net",
        "port": 5000,
        "use_ssl": false,
        "ssl_port": 5001
    },
    "bbs": {
        "name": "My BBS",
        "platform": "BINKTERMPHP/Linux64/1.3.0",
        "sysop": "Sysop"
    },
    "connection": {
        "auto_reconnect": true,
        "reconnect_delay": 30,
        "ping_interval": 60,
        "handshake_timeout": 1,
        "keepalive_timeout": 125
    },
    "rooms": {
        "default": "lobby",
        "auto_join": ["lobby"]
    },
    "messages": {
        "max_length": 140,
        "history_limit": 1000,
        "prune_after_days": 30
    },
    "info": {
        "website": "https://mybbs.example.com",
        "telnet": "mybbs.example.com:23",
        "ssh": "mybbs.example.com:22",
        "description": "A BinktermPHP BBS"
    }
}
Field Description
server.host MRC relay server hostname
server.port Plain TCP port
server.use_ssl Use SSL/TLS connection
server.ssl_port SSL port
bbs.name Your BBS name as it appears on the MRC network (max 64 chars; apostrophes are stripped automatically)
bbs.platform Platform identifier string sent during handshake
bbs.sysop Sysop name
connection.reconnect_delay Seconds to wait before reconnecting after a disconnect
connection.keepalive_timeout Seconds without a PING before treating the connection as dead
rooms.auto_join Rooms to join when a user first enters the WebDoor
messages.history_limit Maximum messages retained per room in the database
messages.prune_after_days Messages older than this are deleted during maintenance
info.* Optional BBS contact info returned by the MRC INFO command

2. Enable the WebDoor

In Admin → WebDoors, find MRC Chat and enable it. Users can then access it via Doors → MRC Chat or directly at /games/mrc.

3. Start the daemon

php scripts/mrc_daemon.php

Options:

Flag Description
--daemon Detach from terminal and run in the background
--pid-file=PATH Write PID to this file (default: data/run/mrc_daemon.pid)
--debug Log raw protocol send/receive for troubleshooting
--log-level=LEVEL Log verbosity level

Keeping the daemon running: crontab (preferred)

Add a @reboot entry to your crontab so the daemon starts automatically when the server boots:

crontab -e

Add this line (adjust the path):

@reboot /usr/bin/php /path/to/binktest/scripts/mrc_daemon.php --daemon --pid-file=/path/to/binktest/data/run/mrc_daemon.pid

Keeping the daemon running: systemd

Alternatively, create /etc/systemd/system/mrc-daemon.service:

[Unit]
Description=BinktermPHP MRC Chat Daemon
After=network.target postgresql.service

[Service]
Type=simple
User=binkterm
WorkingDirectory=/path/to/binktest
ExecStart=/usr/bin/php scripts/mrc_daemon.php
Restart=always
RestartSec=15
StandardOutput=journal
StandardError=journal
SyslogIdentifier=mrc-daemon

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable mrc-daemon
systemctl start mrc-daemon

User Guide

Joining a Room

When a user opens the MRC WebDoor (/games/mrc), the left sidebar lists available rooms. Click a room to join it. Alternatively, type a room name in the text field at the top of the sidebar and press Enter or click the arrow button.

Joining sends a NEWROOM packet to the MRC server, which broadcasts a join announcement to everyone in the room.

Sending Messages

With a room joined, type a message in the input bar at the bottom (max 140 characters) and press Enter or click Send. Messages are delivered to all users in the room across the MRC network.

Private Messages

Click a username in the Users sidebar to open a direct message conversation with that user. The chat header shows a Direct: badge while in private mode. Click the × on the badge to return to room chat.

Private unread message counts appear next to each username and in the Users header badge.

Commands

Type a slash command in the message input field:

Command Description
/motd Request and display the Message of the Day for the current room

Room and User Lists

  • The Rooms sidebar shows all known rooms with their topic and user count. Rooms you have joined are highlighted with a green left border.
  • The Users sidebar lists all users currently in your joined room, with their BBS name below.
  • Join and part announcements appear inline in the message stream.

Admin Integration

MRC can be configured through Admin → MRC without editing config/mrc.json directly. The admin page covers:

  • Enable/disable MRC
  • Server connection settings (host, port, SSL)
  • BBS identification (name, sysop, platform)
  • Connection timeouts
  • Message retention settings
  • BBS info (website, telnet/SSH addresses)

Changes take effect after restarting the daemon.

The MRC connection status indicator (connected / disconnected) appears in the main navigation bar header.

Architecture

Component Purpose
scripts/mrc_daemon.php Long-running daemon; maintains TCP connection to MRC server; reads/writes mrc_outbound table
public_html/webdoors/mrc/api.php HTTP API serving the browser WebDoor; handles poll, send, join, heartbeat, command actions
public_html/webdoors/mrc/mrc.js Browser-side chat client; polls the API every 2 seconds
src/Mrc/MrcClient.php Low-level MRC protocol implementation (packet framing, NEWROOM, IAMHERE, LOGOFF, etc.)
src/Mrc/MrcConfig.php Configuration manager for config/mrc.json

Database Tables

Table Purpose
mrc_messages Inbound messages and server announcements stored for client polling
mrc_outbound Queue of outbound packets waiting to be sent by the daemon
mrc_users Active users per room (is_local=true for WebDoor users, false for remote)
mrc_rooms Known rooms with topic and last activity
mrc_state Key/value store for daemon state (connection status, last ping time)

Presence and Keepalives

  • IMALIVE — Sent by the daemon to the MRC server every ~60 seconds to keep the BBS-level connection alive.
  • IAMHERE — Sent for each local WebDoor user every ~50 seconds to keep their individual session alive on the MRC server.
  • Browser heartbeat — The browser sends a lightweight heartbeat on user activity and via the poll loop to keep the last_seen timestamp current. Users whose last_seen exceeds 10 minutes are pruned and a LOGOFF packet is sent on their behalf.

Troubleshooting

Daemon won't connect

  • Check data/logs/ or journalctl -u mrc-daemon for error messages
  • Verify the server host and port in config/mrc.json (see the server table above)
  • Ensure the port is not blocked by your firewall
  • Try --debug flag to see raw protocol output

Messages not appearing

  • Confirm the daemon is running: check data/run/mrc_daemon.pid and the mrc_state table connected key
  • Confirm the WebDoor is enabled in Admin → WebDoors
  • Check browser console for API errors

BBS name rejected by server

  • Avoid apostrophes, quotes, and tildes (~) in bbs.name — apostrophes are stripped automatically, but other special characters may still cause server-side rejection

Connection drops frequently

  • Increase keepalive_timeout in config/mrc.json if your network has high latency
  • Ensure auto_reconnect is true