PHPackages                             neuralpin/notifyli - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Caching](/categories/caching)
4. /
5. neuralpin/notifyli

ActiveProject[Caching](/categories/caching)

neuralpin/notifyli
==================

Websocket communication app

1.3(2mo ago)04↓50%GPL-3.0-or-laterPHP

Since Mar 3Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/ulisesrendon/notifyli)[ Packagist](https://packagist.org/packages/neuralpin/notifyli)[ RSS](/packages/neuralpin-notifyli/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (5)Dependencies (15)Versions (6)Used By (0)

Notifyli: Real-time Communication with Redis Notifications
==========================================================

[](#notifyli-real-time-communication-with-redis-notifications)

A WebSocket-based real-time messaging system that enables users to communicate in private and public channels. Built-in Redis broker allows external systems to send notifications to specific users in their designated channels.

Overview
--------

[](#overview)

**Primary Goal**: Enable real-time user-to-user communication in private/public channels via WebSocket.

**Secondary Feature**: Redis-based notification broker for sending automated messages from external systems to connected users.

### Key Architecture

[](#key-architecture)

- **User Identification**: Each user must identify themselves with a `user_id` and connect to a specific `room` (channel)
- **Private Channels**: Users typically connect to personal `/user/{user_id}` rooms to receive notifications
- **Public Channels**: Users can join shared rooms for group communication
- **External Integration**: Third-party systems orchestrate notifications via Redis broker, targeting specific users and channels

**Important**: The UI MUST initialize with a `user_id` and `room` before the WebSocket connection is established. This allows the system to:

1. Route direct notifications to the correct user
2. Allow external systems to target specific users for automated notifications
3. Maintain user state in Redis for offline notification handling

Example Implementation Files
----------------------------

[](#example-implementation-files)

This repository includes three example implementations that demonstrate how to integrate the system:

- **`server.php`** - Example WebSocket server initialization. Demonstrates how to configure and start the messaging server with your environment settings.
- **`notification-bridge.php`** - Example notification bridge implementation. Shows how to listen to Redis pub/sub and forward notifications to connected users via WebSocket.
- **`public/index.php`** - Example client UI implementation. Demonstrates user authentication with `user_id`, room selection, and real-time message handling.

These are reference implementations. Adapt them to your specific infrastructure and requirements.

Cloud Production Deployment
---------------------------

[](#cloud-production-deployment)

This guide covers deploying all three components in a production cloud environment.

### Prerequisites

[](#prerequisites)

- Cloud server (Ubuntu 20.04+ recommended) with root access
- PHP 8.2 or higher installed
- Redis server installed and running
- Nginx web server
- Domain name with DNS configured
- SSL certificates (Let's Encrypt recommended)

### Architecture Overview

[](#architecture-overview)

```
┌─────────────────────────────────────────────────────────┐
│                    Nginx (Port 80/443)                  │
│  ┌──────────────────────┬───────────────────────────┐  │
│  │   Web UI (PHP-FPM)   │   WebSocket Proxy (7000)  │  │
│  │  public/index.php    │   → server.php daemon     │  │
│  └──────────────────────┴───────────────────────────┘  │
└─────────────────────────────────────────────────────────┘
                              │
                              ├──►  Redis Pub/Sub
                              │
                 ┌────────────┴────────────┐
                 │ notification-bridge.php │
                 │  (Notification Bridge)  │
                 └─────────────────────────┘

```

### Step 1: Server Preparation

[](#step-1-server-preparation)

```
# Update system
sudo apt update && sudo apt upgrade -y

# Install dependencies
sudo apt install -y nginx php8.2-fpm php8.2-cli php8.2-redis php8.2-mbstring \
    php8.2-xml php8.2-curl redis-server git composer

# Enable Redis
sudo systemctl enable redis-server
sudo systemctl start redis-server

# Verify Redis is running
redis-cli ping
# Expected: PONG
```

### Step 2: Deploy Application Code

[](#step-2-deploy-application-code)

```
# Create application directory
sudo mkdir -p /var/www/notifyli
sudo chown -R www-data:www-data /var/www/notifyli

# Clone or copy your application
cd /var/www/notifyli
# ... upload your code here ...

# Install PHP dependencies
composer install --no-dev --optimize-autoloader

# Set proper permissions
sudo chown -R www-data:www-data /var/www/notifyli
sudo chmod -R 755 /var/www/notifyli
```

### Step 3: Configure Environment

[](#step-3-configure-environment)

Create `/var/www/notifyli/.env`:

```
# WebSocket Server Configuration
APP_WS_SERVER_PROTOCOL=wss  # Use wss for secure WebSocket
APP_WS_SERVER_DOMAIN=your-domain.com
APP_PORT=7000

# Redis Configuration
REDIS_ENABLED=true
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
REDIS_PASSWORD=

# Notification Bridge Configuration
BOT_NAME=NotificationBot
BOT_ROOM=1
```

### Step 4: Configure Nginx (Web UI + WebSocket Proxy)

[](#step-4-configure-nginx-web-ui--websocket-proxy)

Create `/etc/nginx/sites-available/notifyli.conf`:

```
# WebSocket upgrade handling
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;
}

# HTTP to HTTPS redirect
server {
    listen 80;
    listen [::]:80;
    server_name your-domain.com;

    return 301 https://$server_name$request_uri;
}

# Main HTTPS server
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name your-domain.com;

    # SSL Configuration (Let's Encrypt)
    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # Logs
    access_log /var/log/nginx/notifyli-access.log;
    error_log /var/log/nginx/notifyli-error.log;

    # Document root for web UI
    root /var/www/notifyli/public;
    index index.php index.html;

    # Serve static files and PHP
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # PHP-FPM Configuration (Web UI Client)
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;

        # Increase timeouts for long-polling if needed
        fastcgi_read_timeout 300;
    }

    # WebSocket Proxy to server.php daemon
    location /ws {
        proxy_pass http://127.0.0.1:7000;
        proxy_http_version 1.1;

        # WebSocket upgrade headers
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

        # Standard proxy headers
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        # Timeouts for long-lived connections
        proxy_connect_timeout 7d;
        proxy_send_timeout 7d;
        proxy_read_timeout 7d;
    }

    # Deny access to sensitive files
    location ~ /\. {
        deny all;
    }

    location ~ /\.env {
        deny all;
    }
}
```

Enable the site:

```
# Enable site
sudo ln -s /etc/nginx/sites-available/notifyli.conf /etc/nginx/sites-enabled/

# Test configuration
sudo nginx -t

# Reload nginx
sudo systemctl reload nginx
```

### Step 5: SSL Certificate (Let's Encrypt)

[](#step-5-ssl-certificate-lets-encrypt)

```
# Install certbot
sudo apt install -y certbot python3-certbot-nginx

# Obtain certificate (interactive)
sudo certbot --nginx -d your-domain.com

# Auto-renewal is configured automatically
# Test renewal
sudo certbot renew --dry-run
```

### Step 6: Configure Firewall

[](#step-6-configure-firewall)

```
# Allow necessary ports
sudo ufw allow 22/tcp      # SSH
sudo ufw allow 80/tcp      # HTTP
sudo ufw allow 443/tcp     # HTTPS
sudo ufw allow 7000/tcp    # WebSocket (if direct access needed)

# Enable firewall
sudo ufw enable
sudo ufw status
```

### Step 7: Create Log Directories

[](#step-7-create-log-directories)

```
# Create log directory
sudo mkdir -p /var/log/notifyli

# Set permissions
sudo chown -R www-data:www-data /var/log/notifyli
sudo chmod 755 /var/log/notifyli
```

### Step 8: Configure Supervisor

[](#step-8-configure-supervisor)

Install Supervisor:

```
sudo apt install -y supervisor
```

Create `/etc/supervisor/conf.d/notifyli.conf`:

```
[program:notifyli-websocket]
command=/usr/bin/php -q /var/www/notifyli/server.php
directory=/var/www/notifyli
user=www-data
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/notifyli/websocket-server.log
stderr_logfile=/var/log/notifyli/websocket-server-error.log
stopasgroup=true
killasgroup=true

[program:notifyli-notification-bridge]
command=/usr/bin/php -q /var/www/notifyli/notification-bridge.php
directory=/var/www/notifyli
user=www-data
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/notifyli/notification-bridge.log
stderr_logfile=/var/log/notifyli/notification-bridge-error.log
stopasgroup=true
killasgroup=true
```

### Step 9: Enable and Start Services

[](#step-9-enable-and-start-services)

```
# Reload supervisor
sudo supervisorctl reread
sudo supervisorctl update

# Start programs
sudo supervisorctl start notifyli-websocket
sudo supervisorctl start notifyli-notification-bridge

# Check status
sudo supervisorctl status
```

### Step 10: Verify Deployment

[](#step-10-verify-deployment)

```
# Check WebSocket server is listening
sudo netstat -tulpn | grep :7000

# Check logs
sudo supervisorctl tail -f notifyli-websocket
sudo supervisorctl tail -f notifyli-notification-bridge

# Or check log files
sudo tail -f /var/log/notifyli/websocket-server.log
sudo tail -f /var/log/notifyli/notification-bridge.log

# Test Redis connection
redis-cli ping

# Monitor Redis pub/sub
redis-cli SUBSCRIBE notifyli:messages
```

### Managing Services

[](#managing-services)

```
# Start services
sudo supervisorctl start notifyli-websocket notifyli-notification-bridge

# Stop services
sudo supervisorctl stop notifyli-websocket notifyli-notification-bridge

# Restart services
sudo supervisorctl restart notifyli-websocket notifyli-notification-bridge

# View logs
sudo tail -n 100 /var/log/notifyli/websocket-server.log
sudo tail -n 100 /var/log/notifyli/notification-bridge.log

# Follow logs in real-time
sudo supervisorctl tail -f notifyli-websocket
sudo supervisorctl tail -f notifyli-notification-bridge
```

### Maintenance &amp; Monitoring

[](#maintenance--monitoring)

**Daily Restart (Required)**

Create a cron job to restart services daily at 3 AM to mitigate PHP daemon memory growth over time:

```
sudo crontab -e
```

Add:

```
# Restart Notifyli services daily at 3 AM
0 3 * * * supervisorctl restart notifyli-websocket notifyli-notification-bridge
```

**Log Rotation**

Create `/etc/logrotate.d/notifyli`:

```
/var/log/notifyli/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0644 www-data www-data
    sharedscripts
    postrotate
        supervisorctl restart notifyli-websocket > /dev/null 2>&1 || true
        supervisorctl restart notifyli-notification-bridge > /dev/null 2>&1 || true
    endscript
}

```

**Monitoring**

```
# Check service health
supervisorctl status notifyli-websocket
supervisorctl status notifyli-notification-bridge

# Monitor resource usage
top -p $(pgrep -f "server.php")
top -p $(pgrep -f "notification-bridge.php")

# Check Redis memory usage
redis-cli INFO memory

# Monitor active connections
redis-cli CLIENT LIST
```

Integration Guide
-----------------

[](#integration-guide)

### Client UI Integration (Example: public/index.php)

[](#client-ui-integration-example-publicindexphp)

The example UI demonstrates key integration points:

**Required Fields**:

- `user_id`: Unique identifier for the user (required for targeted notifications)
- `room`: Channel identifier (e.g., "lobby", "/user/123")
- `name`: Display name for messages

**WebSocket Connection**:

```
const ws = new WebSocket('wss://your-domain.com/ws');

ws.onopen = () => {
    // Send initial authentication/join message
    ws.send(JSON.stringify({
        type: 'usermsg',
        user_id: userId,
        room: roomId,
        name: userName,
        message: 'joined'
    }));
};

ws.onmessage = (event) => {
    const data = JSON.parse(event.data);

    // Handle direct notifications
    if (data.type === 'direct_message') {
        showNotification(data.message, data.name);
    } else {
        // Handle regular chat messages
        displayMessage(data.message, data.name);
    }
};
```

**Message Types**:

Regular chat message (user to user):

```
{
  "type": "usermsg",
  "user_id": 123,
  "room": "lobby",
  "message": "Hello!",
  "name": "Alice"
}
```

Direct notification (system to user):

```
{
  "type": "direct_message",
  "user_id": 123,
  "message": "Order shipped!",
  "from": "OrderSystem"
}
```

### External System Integration (Publishing Notifications)

[](#external-system-integration-publishing-notifications)

External applications can send notifications to connected users via Redis pub/sub.

**PHP Integration**:

```
