SiamCafe · Blog
WordPress Block Theme Stream Processing —
บทความ

WordPress Block Theme Stream Processing —

เผยแพร่ 28 พฤษภาคม 2569

WordPress Stream Processing

WordPress Block Theme Stream Processing WebSocket SSE Live Dashboard Notification Chat Real-time Custom Block React Performance

TechnologyDirectionProtocolUse CaseComplexity
WebSocketBidirectionalws://Chat, game, collaborationสูง
Server-Sent EventsServer → ClientHTTPNotifications, dashboardต่ำ
Long PollingClient → ServerHTTPFallback, legacy supportกลาง
WordPress HeartbeatBidirectionalAJAXAdmin updates, autosaveต่ำ
REST API PollingClient → ServerHTTPSimple updates, low frequencyต่ำ

SSE Implementation

=== Server-Sent Events with WordPress ===

PHP — SSE Endpoint (wp-content/mu-plugins/sse-endpoint.php)

add_action('rest_api_init', function() {

register_rest_route('stream/v1', '/events', [

'methods' => 'GET',

'callback' => function($request) {

header('Content-Type: text/event-stream');

header('Cache-Control: no-cache');

header('Connection: keep-alive');

header('X-Accel-Buffering: no');

while (true) {

$data = get_latest_updates();

if ($data) {

echo "event: update\n";

echo "data: " . json_encode($data) . "\n\n";

ob_flush();

flush();

}

sleep(2);

if (connection_aborted()) break;

}

},

'permission_callback' => function() {

return is_user_logged_in();

}

]);

});

JavaScript — SSE Client (in Custom Block)

const eventSource = new EventSource('/wp-json/stream/v1/events');

eventSource.addEventListener('update', (event) => {

const data = JSON.parse(event.data);

updateDashboard(data);

});

eventSource.addEventListener('error', (event) => {

console.log('SSE error, reconnecting...');

setTimeout(() => {

eventSource.close();

connectSSE();

}, 5000);

});

from dataclasses import dataclass

@dataclass

class StreamFeature:

feature: str

technology: str

wp_integration: str

example: str

features = [

StreamFeature("Live Dashboard", "SSE",

"Custom Block + REST API SSE endpoint",

"Real-time visitor count, sales, orders"),

StreamFeature("Live Notifications", "SSE",

"mu-plugin + JavaScript EventSource",

"New comment, order, form submission"),

StreamFeature("Live Chat", "WebSocket",

"Node.js WebSocket + WP Auth",

"Customer support, community chat"),

StreamFeature("Live Comments", "SSE",

"REST API polling or SSE",

"Blog comments appear without refresh"),

StreamFeature("Stock Ticker", "WebSocket",

"External WebSocket API + Custom Block",

"Real-time stock/crypto prices"),

]

print("=== Stream Features ===")

for f in features:

print(f" [{f.feature}] Tech: {f.technology}")

print(f" WP Integration: {f.wp_integration}")

print(f" Example: {f.example}")

Custom Block Development

=== WordPress Custom Block for Real-time ===

Create block plugin

npx @wordpress/create-block live-dashboard-block

cd live-dashboard-block

src/edit.js — Editor View

import { useEffect, useState } from '@wordpress/element';

import { useBlockProps } from '@wordpress/block-editor';

export default function Edit() {

const blockProps = useBlockProps();

const [stats, setStats] = useState({

visitors: 0, pageviews: 0, orders: 0

});

useEffect(() => {

const sse = new EventSource('/wp-json/stream/v1/stats');

sse.addEventListener('stats', (e) => {

setStats(JSON.parse(e.data));

});

return () => sse.close();

}, []);

return (

<div {...blockProps}>

<div className="live-dashboard">

<div className="stat">

<span className="label">Visitors</span>

<span className="value">{stats.visitors}</span>

</div>

<div className="stat">

<span className="label">Pageviews</span>

<span className="value">{stats.pageviews}</span>

</div>

<div className="stat">

<span className="label">Orders</span>

<span className="value">{stats.orders}</span>

</div>

</div>

</div>

);

}

block.json

{

"apiVersion": 3,

"name": "my/live-dashboard",

"title": "Live Dashboard",

"category": "widgets",

"icon": "chart-bar",

"attributes": {

"refreshInterval": { "type": "number", "default": 2000 },

"showVisitors": { "type": "boolean", "default": true },

"showOrders": { "type": "boolean", "default": true }

}

}

@dataclass

class BlockComponent:

component: str

file: str

purpose: str

tech: str

components = [

BlockComponent("edit.js", "src/edit.js", "Editor view with SSE preview", "React + WordPress hooks"),

BlockComponent("view.js", "src/view.js", "Frontend SSE connection", "Vanilla JS or React"),

BlockComponent("style.scss", "src/style.scss", "Block styling", "SCSS compiled to CSS"),

BlockComponent("block.json", "block.json", "Block metadata and attributes", "JSON config"),

BlockComponent("index.php", "plugin.php", "Block registration", "register_block_type"),

BlockComponent("sse-endpoint.php", "includes/sse.php", "SSE REST endpoint", "WordPress REST API"),

]

print("\nBlock Components:")

for c in components:

print(f" [{c.component}] File: {c.file}")

print(f" Purpose: {c.purpose} | Tech: {c.tech}")

Performance and Scaling

# === Performance Optimization ===

@dataclass
class PerfConfig:
    setting: str
    value: str
    purpose: str
    impact: str

configs = [
    PerfConfig("SSE Retry Interval", "5000ms",
        "Time before client reconnects after error",
        "Balance between freshness and server load"),
    PerfConfig("Max Connections per User", "1",
        "Prevent multiple SSE connections",
        "Reduce server memory usage"),
    PerfConfig("Heartbeat Interval", "30s",
        "Keep-alive ping to detect dead connections",
        "Clean up stale connections"),
    PerfConfig("Data Push Interval", "2s",
        "How often server checks for new data",
        "Balance freshness vs CPU usage"),
    PerfConfig("Nginx proxy_buffering", "off",
        "Disable buffering for SSE",
        "Required for SSE to work properly"),
    PerfConfig("PHP max_execution_time", "300",
        "Long-running SSE endpoint timeout",
        "Allow SSE connection to stay open"),
    PerfConfig("Redis Pub/Sub", "enabled",
        "Distribute events across multiple servers",
        "Required for horizontal scaling"),
]

print("Performance Configuration:")
for c in configs:
    print(f"  [{c.setting}]: {c.value}")
    print(f"    Purpose: {c.purpose}")
    print(f"    Impact: {c.impact}")

# Nginx config for SSE
# location /wp-json/stream/ {
#     proxy_pass http://wordpress;
#     proxy_buffering off;
#     proxy_cache off;
#     proxy_set_header Connection '';
#     proxy_http_version 1.1;
#     chunked_transfer_encoding off;
#     proxy_read_timeout 300s;
# }

monitoring = {
    "Active SSE Connections": "Track concurrent connections",
    "Message Throughput": "Events per second sent to clients",
    "Connection Duration": "Average SSE connection lifetime",
    "Memory per Connection": "RAM used per SSE connection",
    "Reconnect Rate": "How often clients reconnect",
    "Error Rate": "SSE endpoint errors",
}

print(f"\n\nMonitoring:")
for k, v in monitoring.items():
    print(f"  [{k}]: {v}")

เคล็ดลับ

  • SSE: เริ่มด้วย SSE ก่อน ง่ายกว่า WebSocket เหมาะกับ Dashboard Notification
  • Nginx: ปิด proxy_buffering สำหรับ SSE Endpoint ไม่งั้นข้อมูลจะไม่ส่งทันที
  • Reconnect: ใส่ Reconnect Logic ใน Client เมื่อ Connection หลุด
  • Auth: ตรวจสอบ Authentication ใน SSE Endpoint ด้วย permission_callback
  • Scale: ใช้ Redis Pub/Sub เมื่อต้อง Scale หลาย Server

Stream Processing บน WordPress คืออะไร

Real-time WordPress WebSocket SSE Server-Sent Events Live Dashboard Notification Chat Stock Ticker Comments Block Theme Custom Block React