This software is free and open-source (MIT license). Help prove ZOSCII works by using it.
ZOSCII development is supported entirely by ZOSCIICOIN.
Learn more about ZOSCIICOINThe World's First Truly Quantum Proof Message Queue (MQ) and Data Store when used in conjunction with ZOSCII.
ZOSCII MQ is a minimal, file-based Message Queue (MQ) designed for high-assurance, B2B asynchronous communication. It leverages the file system for durability and uses specific file naming conventions for chronological ordering and message retention. It also can provide a robust message store service.
The architecture offers key advantages over traditional message brokers (like RabbitMQ or Kafka) in specific freight and logistics scenarios:
replikate.php) model allows external partners to control their consumption rate and timing, minimizing your exposure to their network failures.| Feature | ZOSCII MQ (File-Based) | Traditional Broker (RabbitMQ/Kafka) |
|---|---|---|
| Durability | OS/Disk itself (Persistent) | Configurable (Often RAM/DB) |
| Guaranteed Delivery | External Pointer Tracking (Puller's responsibility) | Built-in ACK/Offset Tracking |
| Architecture | Simple HTTP Endpoint + File System | Complex Daemon/Cluster Management |
ZOSCII MQ uses a simple HTTP API (via index.php) for publishing and fetching messages, and a cron script (replikate.php) for B2B integration.
Messages are published using an HTTP GET request to the index.php endpoint.
Endpoint:
/index.php?action=publish
JSON Responses:
The main ZOSCII MQ index.php gives back it's responses as either binary data with a filename as it's Content-Disposition *, or as JSON messages in the format shown here. If possible it is always good to check the system. The error if it has a value is important. If there is no value in the error, then the result is valid. A message may be provided regardless of errors or results.
{
"system":"ZOSCII MQ",
"version":"1.0",
"error":"",
"message":"Message published.",
"result":[]
}
* Refer to the implementation of the fetchNextMessage function within replikate.php for an example of how to handle the binary and JSON responses.
| Description | Do | Do Not |
|---|---|---|
| check the filename from the Content-Disposition | Do | - |
checking the message is from ZOSCII MQ * response.system === "ZOSCII MQ" |
Do | - |
checking that there are no errors response.error.length === 0 |
Do | - |
checking if a response message is provided if (response.message.length > 0) { // display the message } |
Do | - |
placing logic on the response message if (response.message === "Message Published") { // do someting } |
- | Do Not |
* Note: It is possible to confuse JSON messages stored in ZOSCII MQ vs those JSON messages from ZOSCII MQ itself. However it shouldn't hapen if you first check the filename from within the Content-Disposition. Checking if response.system is present and whether it is "ZOSCII MQ" will make this more robust.
| Parameter | Required | Description | Example Value |
|---|---|---|---|
action |
Yes | Must be publish. |
publish |
q |
Yes | The name of the target queue. | customer_a |
msg |
Yes | The raw message payload (should be URL-encoded). | {"item":"A"} |
n |
Optional | An optional NONCE or GUID to prevent retries from duplicating messages in the queue. | a1b2c3d4-e5f6-4000-8000-0123456789ab |
r |
Optional | Retention Days (RRRR). 0000 = no expected retention (suitable for testing). | 7 |
Example Command (HTTP):
GET /index.php?action=publish&q=customer_b&r=30&msg=%7B%22sku%22%3A%20%22123%22%7D&n=a1b2c3d4-e5f6-4000-8000-0123456789ab
JSON Response:
{
"system":"ZOSCII MQ",
"version":"1.0",
"error":"",
"message":"Message published.",
"result":[]
}
Filename Format:
The message is saved as a file in the queues/QUEUE_NAME/ directory with the format: YYYYMMDDHHNNSSCCCC-RRRR-GUID.bin
Messages are fetched sequentially using the unique filename as a pointer. The consumer must track this pointer (the after parameter) to ensure guaranteed, chronological delivery.
Endpoint:
/index.php?action=fetch
| Parameter | Required | Description | Example Value |
|---|---|---|---|
action |
Yes | Must be fetch. |
fetch |
q |
Yes | The name of the source queue to read from. | customer_b |
after |
Optional | The Pointer. The filename of the LAST successfully processed message. Leave blank or omit for the very first message. | 202510300900000001-0000-ed207f80-9fee-428d-8fad-0133255e1790.bin |
Success Response:
Content-Disposition header) as its pointer.after parameter).For external partners (e.g. ABC Ltd) to pull data from your (e.g. XYZ Ltd) queue, they should run a dedicated cron job on their server (e.g. ABC_LOCAL_SERVER).
Script:
replikate.php
Setup:
Endpoint:
/replikate.php
| Parameter | Required | Description | Example Value |
|---|---|---|---|
url |
Yes | The URL of the source server's index.php |
https://XYZ_REMOTE_SERVER/index.php |
sq |
Yes | The name of the source queue to read from | XYZ_REMOTE_QUEUE (e.g. abc_orders |
tq |
Optional | The name of the target queue on the partner's server | ABC_LOCAL_QUEUE (e.g. my_orders) |
Example Command for Queue to Queue replication (HTTP):
GET /replikate.php?url=https://SOURCESERVER/index.php&sq=SOURCEQUEUE&tq=TARGETQUEUE
The script manages the state/pointer file (replikate_state_SOURCEQUEUE.txt) automatically.
Example Command for Queue to Store replication (HTTP):
GET /replikate.php?url=https://SOURCESERVER/index.php&sq=SOURCEQUEUE
Messages are stored using an HTTP GET request to the index.php endpoint.
Endpoint:
/index.php?action=store
| Parameter | Required | Description | Example Value |
|---|---|---|---|
action |
Yes | Must be store. |
store |
msg |
Yes | The raw message payload (should be URL-encoded). | {"item":"A"} |
n |
Optional | An optional NONCE or GUID to prevent retries from duplicating messages in the data store. | a1b2c3d4-e5f6-4000-8000-0123456789ab |
r |
Optional | Retention Days (RRRR). 0000 = no expected retention (suitable for testing). | 7 |
Example Command (HTTP):
GET /index.php?action=store&r=30&msg=%7B%22sku%22%3A%20%22123%22%7D&n=a1b2c3d4-e5f6-4000-8000-0123456789ab
JSON Response:
{
"system":"ZOSCII MQ",
"version":"1.0",
"error":"",
"message":"Message stored.",
"result":"202511021826110000-0030-9cc1980a-1719-440a-9650-6991c9cba11d.bin"
}
Filename Format:
The message is saved as a file in the store/x/y/z/ directory with the format: YYYYMMDDHHNNSSCCCC-RRRR-GUID.bin. The file will be returned if the storing of the message is successful. You will need to note this filename for later fast retrieval.
For later retrieval of the message, you must note the response.result.
Messages are retrieved from the data store by using the previously returned filename. The consumer must track this filename if fast retrieval is required.
Endpoint:
/index.php?action=retrieve
| Parameter | Required | Description | Example Value |
|---|---|---|---|
action |
Yes | Must be retrieve. |
retrieve |
name |
Yes | The Name. The result of a past successful store action. | x202511021826110000-0030-9cc1980a-1719-440a-9650-6991c9cba11d.bin |
Success Response:
Content-Disposition header) to determin if the file was fetched.JSON Error Response:
{
"system":"ZOSCII MQ",
"version":"1.0",
"error":"Invalid name 'x202511021826110000-0030-9cc1980a-1719-440a-9650-6991c9cba11d.bin'.",
"message":"",
"result":[]
}
Messages are retrieved from the data store by using the previously returned filename. The consumer must track this filename if fast retrieval is required.
Endpoint:
/index.php?action=scan
Success Response:
{
"system":"ZOSCII MQ",
"version":"1.0",
"error":"",
"message":"",
"result":[
"202511021259550001-0005-5192e106-7a99-4418-98eb-8d4cb4c6aa3a-u.bin",
"202511021259550001-0005-be2b00c1-9419-4661-8c1d-2219780c7980-u.bin"
]
}
Once messages have been scanned for, then identified, they can then be flagged as identified.
Endpoint:
/index.php?action=identify
| Parameter | Required | Description | Example Value |
|---|---|---|---|
action |
Yes | Must be identify. |
identify |
names |
Yes | The raw message payload (should be URL-encoded). | [
"202511021259550001-0005-5192e106-7a99-4418-98eb-8d4cb4c6aa3a-u.bin",
"202511021259550001-0005-be2b00c1-9419-4661-x8c1d-2219780c7980-u.bin"
] |
Example Command (HTTP):
GET /index.php?action=identify&names=["202511021259550001-0005-5192e106-7a99-4418-98eb-8d4cb4c6aa3a-u.bin","x202511021259550001-0005-be2b00c1-9419-4661-8c1d-2219780c7980-u.bin"]
Success Response:
{
"system":"ZOSCII MQ",
"version":"1.0",
"error":"",
"message":"Returned messages identified.",
"result":[
"202511021259550001-0005-5192e106-7a99-4418-98eb-8d4cb4c6aa3a.bin"
]
}
The system is file-based and requires a dedicated root directory:
./
|-- index.php (HTTP API: Publish/Fetch)
|-- replikate.php (Cron: External Puller)
|-- claireup.php (Cron: Retention Cleanup)
|-- nonce/ (Optional nonce files go here)
|-- queues/
| |-- customer_a/ (Queue 1)
| |-- customer_a/locks/ (Queue 1 lock files)
| | |-- *.bin
| |-- customer_b/ (Queue 2)
| |-- customer_b/locks/ (Queue 2 lock files)
| | |-- *.bin
|-- states/ (State Files are here for Replicators)
| | |-- replikate_state_*.txt
|-- store/ (Data Store Files are here)
|-- statissa.php (Statistics, it's better to place statissa elsewhere)
Two cron jobs must be set up on the ZOSCII MQ server to ensure stability:
claireup.php)This job ensures disk space is managed by deleting expired messages based on the **RRRR** value in the filename. It processes **all queues globally**.
| Setting | Value | Description |
|---|---|---|
| Script | claireup.php |
The retention management script. |
| Schedule | Once daily (e.g., 0 0 * * *) |
Runs at midnight to clear the previous day's expired files. |
| Action | Deletes any message file where Current Time $\ge$ (Message Time + RRRR days). It deletes messages with RRRR=0000. |
Cron Example:
Although it's possible to run claireup.php from a browser it is recommended to run it from cron if possible. To run it from the browser, you will first need to change the CLI_ONLY constant to FALSE from within the claireup.php file. If you do that, you are best ensure that it cannot be run by unauthorised parties if you don't want it to run.
0 0 * * * /usr/bin/php /path/to/claireup.php
ZOSCII MQ supports two primary deployment patterns, each optimized for different use cases:
replikate.php for high availability
Primary Server (HQ) Backup Server (DR Site)
ZOSCII MQ โโโโโโ ZOSCII MQ
[All Queues] replikate [Mirror Copy]
(periodic)
Single queue, multiple readers - built-in ZOSCII MQ capability
Primary Server
ZOSCII MQ
[company_announcements]
โ
โโโโโโโโโโโโโโผโโโโโโโโโโโโโฌโโโโโโโโโโโโโ
โ โ โ โ
John's PC Mary's PC Bob's PC ... 1,000+ PCs
1 message published โ 1,000+ PCs all fetch from same queue
Each PC independently reads the same messages
No replication needed - standard ZOSCII MQ behavior
Use Cases:
Benefits:
Distribute load across multiple servers for scale/geography
Primary Server (HQ)
ZOSCII MQ
[company_announcements]
โ
โโโโโโโโโโโโโดโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
โ โ โ
replikate.php replikate.php replikate.php
โ โ โ
Server A (Sydney) Server B (Tokyo) Server C (London)
ZOSCII MQ ZOSCII MQ ZOSCII MQ
โ โ โ
โโโโโโโผโโโโโโ โโโโโโโผโโโโโโ โโโโโโโผโโโโโโ
โ โ โ โ โ โ โ โ โ
PC1 PC2 PC500 PC501 PC502 PC1000 ... PC2000 PC3000
1 message โ striped to 3 regional servers โ 3,000+ PCs globally
Each regional server services local PCs (lower latency)
Use Cases:
Benefits:
Without Striping (Pattern 1):
With Striping (Pattern 2):
Result: 1,000ร reduction in WAN bandwidth usage
replikate.php
Business A (AWS) Business B (AWS) Business C (AWS)
ZOSCII MQ Docker ZOSCII MQ Docker ZOSCII MQ Docker
[Push anytime] [Push anytime] [Push anytime]
โ โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโดโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
Head Office Server (Local)
ZOSCII MQ
[Pulls 24/7 via replikate.php]
[Aggregates all business data]
| Aspect | Internal Message Bus | AWS B2B Integration |
|---|---|---|
| Network | 1Gb+ LAN | Internet (100-500 Mbps) |
| Throughput/Day | Tens of thousands | Thousands (per business) |
| Traffic Pattern | 24/7 potential | Business hours (bursty) |
| Deployment | On-premise / Private cloud | AWS Docker (1 per customer) |
| Replication | Optional (DR backup) | Continuous (aggregation) |
| Cost Model | Single server cost | $5-50/month per customer |
| Use Case | Internal operations | B2B document exchange |
Deploying ZOSCII MQ using Docker provides an **instant, persistent message queue** solution. There are three primary deployment strategies for managing the deployment environment and persistent queue data (messages and nonces):
This strategy is best for quick setup and development environments. It uses **Docker Named Volumes** which Docker automatically manages on the host machine.
docker-compose.yml uses Named Volumes (zoscii_data and zoscii_nonce).The volumes section in the docker-compose.yml looks like this:
volumes:
# Data is mapped to Docker-managed volumes defined at the bottom of the file.
- zoscii_data:/app/queues
- zoscii_nonce:/app/nonce
volumes:
zoscii_data:
zoscii_nonce:
This strategy gives you full control over where the queue data resides. This is essential for environments where you need to explicitly back up, monitor, or manage the queue files using host-level tools (like rsync or specific backup agents).
./zoscii-data/).The volumes section in the docker-compose.yml is modified to specify the host path:
volumes:
# The host path (./zoscii-data) is explicitly mapped to the container path.
- ./zoscii-data/queues:/app/queues
- ./zoscii-data/nonce:/app/nonce
# NOTE: Named volumes are NOT defined when using Bind Mounts.
If you wish to deploy without installing Docker or running a package manager locally, the best method is a **Serverless Container Service** that manages the container's lifecycle and infrastructure.
/app/queues directory must be mounted to a cloud file system service (like **AWS EFS** or **Google Cloud Filestore**) during deployment setup. This replaces the Docker volume concept with a network file system.Once your ZOSCII MQ Docker image is pushed to a public registry (via automated build, e.g., GitHub Actions), you can deploy it in a few clicks.
claireup.php)Since claireup.php is designed to be run from the command line (CLI), you can execute it manually inside the running container:
docker-compose exec zoscii-mq php /app/claireup.php
You can automate this by setting up a host-level cron job that calls the docker-compose exec command every minute. **Note for Strategy 3 (Cloud Deploy):** For cloud deployments, you must use the cloud provider's native scheduling tools (e.g., **AWS CloudWatch Events/EventBridge** or **Google Cloud Scheduler**) to execute the cleanup command on the running container.
| Feature | ZOSCII MQ | Apache Kafka | RabbitMQ |
|---|---|---|---|
| Core Size | ~35 KB (PHP) | ~160 MB + JVM | ~150 MB + Erlang |
| Runtime Dependencies | PHP only | JVM, Zookeeper/KRaft | Erlang VM |
| Memory Footprint | ~10-50 MB | 6-32+ GB typical | 1-4 GB typical |
| Protocol | HTTP/REST native | Binary (needs REST Proxy) | AMQP + HTTP API |
| Distributed Architecture | Federated (via replikate.php) | Centralized cluster | Cluster with federation |
| Cross-Organization B2B | โ Native (pull model) | โ Complex (VPN/proxy) | โ ๏ธ Possible (federation) |
| Message Storage | Direct file access | Segmented logs | Mnesia DB/Queues |
| Retention Model | Per-message (RRRR days) | Per-topic configuration | TTL or consumed |
| Setup Time | < 5 minutes | Hours to days | 30-60 minutes |
| Debugging | ls, cat, grep files | JMX, complex tools | Management UI |
| Metric | ZOSCII MQ | Apache Kafka | RabbitMQ |
|---|---|---|---|
| Primary Deployment Context | B2B over Internet | Internal datacenter/LAN | Internal datacenter/LAN |
| Throughput - Internet (100-500 Mbps typical) (>1KB messages) |
โ
Good Network-limited Thousands-tens of thousands/day |
โ
Good Network-limited Thousands-tens of thousands/day |
โ
Good Network-limited Thousands-tens of thousands/day |
| Throughput - Internet (100-500 Mbps typical) (>100KB messages) |
โ
Optimal Designed for this Thousands/day Zero knowledge maintained |
โ ๏ธ Limited Network bottleneck Hundreds-low thousands/day |
โ ๏ธ Limited Network bottleneck Hundreds-low thousands/day |
| Throughput - Internet (100-500 Mbps typical) (>1MB messages) |
โ
Handles Well Network-limited Hundreds/day |
โ Poor Network + config issues Tens-hundreds/day |
โ Poor Network + memory issues Tens/day |
| 1 Gb LAN Performance (Internal Network) | |||
| Throughput - 1Gb LAN (Single node) (>1KB messages) |
โ
Excellent Disk I/O limited Tens of thousands/day 100-1,000 msg/sec |
โ
Optimal Peak performance Millions/day 10,000-100,000+ msg/sec |
โ
Excellent Strong performance Hundreds of thousands/day 5,000-20,000 msg/sec |
| Throughput - 1Gb LAN (Single node) (>100KB messages) |
โ
Excellent Still in designed range Tens of thousands/day Consistent performance |
โ ๏ธ Good (needs tuning) Config changes needed Tens of thousands/day Efficiency drops |
โ ๏ธ Degraded Memory pressure Low thousands/day Performance impact |
| Throughput - 1Gb LAN (Single node) (>1MB messages) |
โ
Excellent File-based handles naturally Thousands/day No memory pressure |
โ Poor Major config needed Hundreds/day Batching ineffective |
โ Not Recommended Severe issues Dozens/day Can crash under load |
| Horizontal Scaling | Federated (independent nodes) | Add brokers to cluster | Add nodes to cluster |
| Geographic Distribution | โ Excellent (federation) | โ ๏ธ Complex (MirrorMaker) | โ Good (federation) |
| Security Aspect | ZOSCII MQ | Apache Kafka | RabbitMQ |
|---|---|---|---|
| Message Handling | Transparent pass-through Data stored as-is |
Transparent pass-through Data stored as-is |
Transparent pass-through Data stored as-is |
| Server Knowledge | โ
Zero knowledge by design Built for ITS/ZOSCII Pure binary storage |
โ ๏ธ Partial knowledge Keys, headers, offsets Schema registry possible |
โ Message awareness Routing, properties, TTL Content-based routing |
| Data Storage | Raw bytes as provided No built-in encryption |
Raw bytes as provided No built-in encryption |
Raw bytes as provided No built-in encryption |
| Public Queue Sharing | โ
Safe even if public ITS/ZOSCII perfect secrecy Multiple parties, one queue |
โ Requires encryption Vulnerable if exposed Computational security only |
โ Requires encryption Vulnerable if exposed Computational security only |
| Queue/Topic Security | โ
Can use secret names Capability-based access No enumeration |
โ Topics visible Listed in metadata Requires ACLs |
โ ๏ธ Queues visible Listed in management Requires permissions |
| Default Security | โ ๏ธ None (relies on web server) | โ None (wide open) | โ ๏ธ Guest/guest (localhost only) |
| Authentication | HTTP Basic/Digest/OAuth (.htaccess, PHP session) |
SASL (PLAIN/SCRAM/GSSAPI) SSL certificates |
PLAIN/AMQPLAIN/EXTERNAL LDAP, OAuth 2.0 |
| Transport Encryption | โ HTTPS (standard) | TLS/SSL (must configure) | TLS/SSL (built-in) |
| Message Encryption | โ
ITS-ready (mentioned in docs) Application-level |
Application-level only | Application-level only |
| Authorization/ACLs | Web server level PHP app logic |
Complex ACLs Per-topic permissions |
User/vhost permissions Regex-based |
| Cross-Organization B2B | โ
Each org owns security No shared credentials |
โ Shared cluster access VPN/proxy complexity |
โ ๏ธ Federation possible Shared credentials |
| Attack Surface | HTTP endpoint only Standard web security |
Binary protocol 9092+ other ports Zookeeper exposure |
AMQP + Management Multiple ports |
| Audit Trail | Web server logs Filesystem timestamps |
Audit log (enterprise) Complex setup |
Firehose tracer Management events |
| Security Setup Complexity | โ Simple (web standard) | โ Very complex (JAAS, keystores, ACLs) |
โ ๏ธ Moderate |
| Network Isolation | โ
Standard firewall rules HTTP/HTTPS only |
Multiple ports Internal communication |
Multiple ports Clustering ports |
| Data at Rest | Plain files (filesystem encryption) |
Plain logs (filesystem encryption) |
Mnesia DB (filesystem encryption) |
| Multi-Tenancy Security | โ
Complete isolation (separate servers) |
โ ๏ธ Namespace separation | โ Vhost isolation |
ZOSCII MQ is purpose-built for ZOSCII (100% secure Information Theoretic Encoding) with complete zero-knowledge architecture.
"The server doesn't know what it doesn't need to know."
ZOSCII MQ Web Radio is a JavaScript-based web radio player that consumes media from ZOSCII MQ queues. It provides a complete, embeddable radio station interface for websites, supporting multi-channel playback, queue management, and ZOSCII-encoded content.
The Web Radio system consists of two main components:
The player requires specific HTML elements with designated class names for the JavaScript to bind to:
<div id="geZOSCIIMQPlayer" class="gsZOSCIIPlayer">
<!-- Configuration Section -->
<div class="geConfigSection">
<input class="geQueueUrl" type="text" value="index.php">
<select class="geQueueNames" multiple></select>
<input class="geROMFile" type="file">
<select class="geBehavior">
<option value="repeatQueue">Repeat Channel</option>
<option value="repeatAllQueues">Repeat All Channels</option>
<option value="nextQueue">Next Channel</option>
<option value="waitAtEnd">Wait at End</option>
<option value="stopAtEnd">Stop at End</option>
<option value="randomQueue">Random Channel</option>
</select>
</div>
<!-- Control Buttons -->
<button class="geStartButton">Connect to Channel</button>
<button class="geStopButton">Stop</button>
<button class="geToggleButton">Pause</button>
<button class="gePreviousButton">Previous</button>
<button class="geNextButton">Next</button>
<!-- Status Display -->
<div class="geStatus"></div>
<div class="geNowPlaying"></div>
<!-- Progress Visualization -->
<div class="geProgressBar"></div>
<div class="geOscilloscope"></div>
<!-- Media Display -->
<audio class="gePlayer"></audio>
<div class="geImage"></div>
<div class="geText"></div>
</div>
<script src="js/zosciiradioplayer.js"></script>
<script>
$(document).ready(function() {
var m_strComponentID = 'geZOSCIIMQPlayer';
function element(strScope, strClass) {
return $('.' + strClass, '#' + strScope);
}
// Populate available channels
var arrQueueNames = ['Cyborg Unicorn', 'ZOSCII'];
var objQueueSelect = element(m_strComponentID, 'geQueueNames');
for (var i = 0; i < arrQueueNames.length; i++) {
objQueueSelect.append('<option selected value="' +
arrQueueNames[i] + '">' + arrQueueNames[i] + '</option>');
}
// Define callbacks
function onStart() {
// Hide config, show controls
element(m_strComponentID, 'geConfigSection').hide();
element(m_strComponentID, 'geStartButton').hide();
element(m_strComponentID, 'geStopButton').show();
element(m_strComponentID, 'geToggleButton').show();
// Return selected queues to player
return element(m_strComponentID, 'geQueueNames').val() || [];
}
function onStop() {
// Show config, hide controls
element(m_strComponentID, 'geConfigSection').show();
element(m_strComponentID, 'geStartButton').show();
element(m_strComponentID, 'geStopButton').hide();
}
// Initialize player
var objRadioPlayer = new ZOSCIIRadioPlayer(m_strComponentID, {
clearImageAfterSong: true,
clearTextAfterImage: true,
clearTextAfterSong: true,
imageDelay: 10,
onStart: onStart,
onStop: onStop
});
});
</script>
| Option | Type | Default | Description |
|---|---|---|---|
clearImageAfterSong |
Boolean | false |
Clear displayed images when MP3 finishes playing |
clearTextAfterImage |
Boolean | false |
Clear displayed text when new image is shown |
clearTextAfterSong |
Boolean | false |
Clear displayed text when MP3 finishes playing |
imageDelay |
Number | 10 |
Seconds to display image before moving to next item |
maxTextLength |
Number | 16384 |
Maximum text file size to display (in bytes) |
onStart |
Function | null |
Callback when player starts. Must return array of queue names |
onStop |
Function | null |
Callback when player stops |
onPrevious |
Function | null |
Callback when previous track button clicked |
onNext |
Function | null |
Callback when next track button clicked |
onToggle |
Function | null |
Callback when pause/play toggled. Receives boolean parameter |
| Behavior | Description |
|---|---|
repeatQueue |
Repeat current channel indefinitely |
repeatAllQueues |
Cycle through all selected channels, repeating |
nextQueue |
Move to next channel when current ends (no repeat) |
waitAtEnd |
Wait 30 seconds at end of channel for new content |
stopAtEnd |
Stop playback when channel ends |
randomQueue |
Switch to random channel when current ends |
The fetch action now supports optional offset and length parameters for partial file retrieval, enabling true streaming and progressive download capabilities:
POST /index.php
Content-Type: application/x-www-form-urlencoded
action=fetch&q=music_channel&after=20251117120000.bin&offset=0&length=65536
| Parameter | Required | Description |
|---|---|---|
offset |
Optional | Byte offset to start reading from (0-based) |
length |
Optional | Number of bytes to read from offset position |
Response Headers:
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="20251117120100.bin"
Content-Length: 65536
X-ZOSCII-Offset: 0
X-ZOSCII-Total-Length: 3145728
Use Cases:
Note: The current Web Radio player implementation fetches complete files. The streaming infrastructure is available for custom implementations.
The ZOSCII MQ Publisher provides a simple interface for uploading content to queues.
<div id="geZOSCIIMQPublisher" class="gsZOSCIIPublisher">
<input class="geQueueURL" type="text" value="index.php">
<input class="geQueueName" type="text" value="test_radio">
<input class="geRetention" type="number" value="7">
<input class="geROMFile" type="file">
<input class="gePublishFile" type="file">
<button class="gePublishFileButton">Publish File</button>
<div class="geStatus"></div>
</div>
<script src="js/tozoscii.js"></script>
<script src="js/zosciipublisher.js"></script>
<script>
$(document).ready(function() {
var objPublisher = new ZOSCIIMQPublisher('geZOSCIIMQPublisher', {});
});
</script>
publish actionZOSCII MQ Web Radio supports three file types that are automatically detected and displayed appropriately. The power comes from sequencing these types in the queue to create rich multimedia experiences.
imageDelay option)maxTextLengthThe player processes queue items sequentially, allowing you to create different listening experiences by controlling the order you publish content:
Publishing Pattern: MP3 โ MP3 โ MP3 โ MP3
User Experience: Continuous music playback, classic radio station
Queue: "classic_rock"
โโ 001-song1.mp3
โโ 002-song2.mp3
โโ 003-song3.mp3
โโ 004-song4.mp3
Publishing Pattern: JPEG โ MP3 โ JPEG โ MP3 โ JPEG โ MP3
User Experience: Album art appears before each song, then music plays
Queue: "visual_music"
โโ 001-album-art-1.jpg (displays 10 seconds)
โโ 002-song1.mp3 (plays until end)
โโ 003-album-art-2.jpg (displays 10 seconds)
โโ 004-song2.mp3 (plays until end)
โโ 005-band-photo.jpg (displays 10 seconds)
โโ 006-song3.mp3 (plays until end)
Tip: Configure clearImageAfterSong: true to remove the image when music finishes.
Publishing Pattern: JPEG โ TEXT โ MP3 โ JPEG โ TEXT โ MP3
User Experience: Album art, then lyrics/info, then music with lyrics visible
Queue: "lyric_radio"
โโ 001-album-cover.jpg (displays 10 seconds)
โโ 002-lyrics.txt (displays immediately after image)
โโ 003-song.mp3 (plays with lyrics visible)
โโ 004-next-album.jpg (displays 10 seconds, optionally clears lyrics)
โโ 005-next-lyrics.txt (displays immediately)
โโ 006-next-song.mp3 (plays with new lyrics visible)
Configuration Options:
clearTextAfterImage: true - Lyrics disappear when new album art appearsclearTextAfterImage: false - Lyrics stay visible until new text file loadsclearTextAfterSong: true - Lyrics disappear when song endsExample: Multilingual Lyrics Display
Text files can contain lyrics in 15+ languages simultaneously, all rendered correctly:
[Verse 1 - Pain & Suffering]
Why do we fight? (English)
ไธบไปไนๆไปฌๆๆ๏ผ(Chinese: Why do we fight?)
ยฟPor quรฉ hay dolor? (Spanish: Why is there pain?)
เคนเคฎ เคเฅเคฏเฅเค เคฐเฅเคคเฅ เคนเฅเค? (Hindi: Why do we cry?)
ูู
ุงุฐุง ูุนุงููุ (Arabic: Why do we suffer?)
The player's architecture supports adding new content types in the future:
New types can be detected via file signatures and handled with appropriate display logic in the identifyType() and dispatch functions.
Minimal player for a single radio channel (see player-raw.html):
<!-- Unstyled, functional player -->
<div id="player">
<input class="geQueueUrl" value="https://radio.example.com/index.php">
<textarea class="geQueueNames">my_channel</textarea>
<input class="geROMFile" type="file">
<button class="geStartButton">Start</button>
<audio class="gePlayer" controls></audio>
</div>
Complete radio station interface with:
// Allow users to manage favorite stations
var arrStations = [
{ name: 'Station A', url: 'https://a.com/index.php', queues: ['music', 'talk'] },
{ name: 'Station B', url: 'https://b.com/index.php', queues: ['jazz', 'news'] }
];
// Populate station selector
// User selects station, queues auto-populate
// Player connects to selected station's URL
All user-generated content is properly escaped:
htmlEncode() functionFor cross-origin radio players, configure the MQ server:
# Apache .htaccess
Header set Access-Control-Allow-Origin "https://yourradio.com"
Header set Access-Control-Allow-Methods "POST, GET, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type"
ROM files are processed client-side and never uploaded to the server, protecting the encryption key.
repeatAllQueues for continuous playbackwaitAtEnd (checks for new content every 30s)stopAtEnd (user manually advances)<!-- In WordPress post/page -->
<div id="radio"></div>
<script src="/wp-content/themes/mytheme/js/zosciiradioplayer.js"></script>
<script>
// Initialize player with WordPress theme styling
</script>
Cyborg Unicorn Radio: cyborgunicorn.com.au/radio
Features:
| Browser | Minimum Version | Notes |
|---|---|---|
| Chrome | 49+ | Full support |
| Firefox | 52+ | Full support |
| Safari | 10+ | Full support |
| Edge | 14+ | Full support |
| IE 11 | 11 | Limited (no Web Audio oscilloscope) |
Note: ES5 compatibility ensures the player works on older browsers. Web Audio API features (oscilloscope) gracefully degrade on unsupported browsers.
ZOSCII MQ Web Radio supports the same federated replication model as standard ZOSCII MQ queues. Any radio station can replicate content from another station's queue using replikate.php:
// Station B replicates from Station A's radio queue
GET /replikate.php?url=https://stationA.com/index.php&sq=music_channel&tq=replicated_music
Architectural Principle: The system is intentionally designed so that you cannot prevent replication without preventing playback. If someone can listen to your station, they can replicate it. This fundamental design choice enables the democratized, federated network model while forcing content creators to use ROM-based access control rather than technical restrictions.
This enables:
The ROM file serves as both an encoding key and an access control mechanism for radio channels. This enables two distinct distribution models:
Use Case: Monetization, subscriber-only content, or restricted distribution
Strategy:
Example Scenarios:
Access Control: ZOSCII provides Information Theoretic Security (ITS) - the world's first practical implementation that is mathematically more secure than traditional encryption and dramatically faster to decode. The encoded content is mathematically unbreakable without the ROM. However, this doesn't prevent piracy - someone can share the ROM file just as easily as sharing the content itself. The protection comes from controlling who has the ROM, not from making the content uncrackable. For monetization, you must manage ROM distribution carefully (subscriptions, unique ROMs per customer, legal agreements, etc.).
Use Case: Maximum reach, democratized radio, community content
Strategy:
Benefits:
Recommendation: If you want your radio station to be part of a global, open network where anyone can listen and stations can freely replicate each other's content, use the official Cyborg Unicorn Logo ROM file included with the ZOSCII MQ Web Radio Player distribution.
Stations can operate both public and private channels simultaneously:
Station Configuration:
โโ Public Queue: "free_music" (Cyborg Unicorn ROM - open access)
โโ Premium Queue: "exclusive_content" (Custom ROM - paid subscribers)
โโ Archive Queue: "classics" (Cyborg Unicorn ROM - open access)
This allows monetization of premium content while building audience with free content.
Station A (Origin - Australia)
Queue: "aussie_rock"
[Cyborg Unicorn ROM]
โ
โโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโ
โ โ โ
โผ โผ โผ
Station B Station C Station D
(US Mirror) (EU Mirror) (Asia Mirror)
replikate replikate replikate
โ โ โ
โผ โผ โผ
500 US users 300 EU users 200 Asia users
Result: 1,000 users globally accessing content with regional low-latency, all using the same public ROM. Station A publishes once, content distributed worldwide automatically.
| Distribution Model | ROM Type | Distribution Method | Use Case |
|---|---|---|---|
| Open Network | Cyborg Unicorn Logo ROM | Bundled with player download | Public radio, community stations |
| Paid Access | Custom ROM | Email after payment | Subscription services, premium content |
| Membership | Custom ROM | Member portal download | Clubs, organizations, private groups |
| One-Time Purchase | Unique ROM per purchase | Download link after purchase | Album sales, artist direct distribution |
| Corporate Internal | Custom ROM | IT department, intranet | Company radio, training content |
Vision: A global network of independent radio stations, all using the Cyborg Unicorn Logo ROM, freely replicating each other's content and creating a censorship-resistant, truly open radio ecosystem.
Join the Network: Use the official Cyborg Unicorn Logo ROM for your station and become part of the world's first truly open, federated web radio network.
| Metric | Value | Notes |
|---|---|---|
| JavaScript Size | ~25 KB | Unminified |
| Memory Footprint | 5-15 MB | Varies with ROM size |
| Fetch Interval | ~2 seconds | Between tracks |
| ZOSCII Decode Speed | ~100 MB/s | Modern browsers |
| Max Concurrent Players | Unlimited | Client-side only |
ZOSCII MQ's replikate.php enables a unique federated architecture:
Company A (Sydney) Company B (Tokyo) Company C (London)
ZOSCII MQ โโโโ ZOSCII MQ โโโโ ZOSCII MQ
โ โ โ
[Own Control] [Own Control] [Own Control]
[Own Security] [Own Security] [Own Security]
[Own Data] [Own Data] [Own Data]
Each node operates independently - no central point of failure, no shared infrastructure, perfect for B2B logistics and freight forwarding where different organizations need to maintain sovereignty over their systems.
| Cost Factor | ZOSCII MQ | Kafka | RabbitMQ |
|---|---|---|---|
| Infrastructure | $5-50/month (VPS) | $500-5000+/month | $100-1000/month |
| Operational Expertise | Junior PHP dev | Senior DevOps team | Mid-level DevOps |
| Monitoring Tools | Built-in (statissa.php) | Prometheus/Grafana/etc | Management plugin |
| High Availability | rsync/filesystem backup/replikate.php | Complex cluster config | Cluster + mirroring |