Pular para o conteúdo principal

Known Limitations & Quirks

This page documents important limitations and behaviors to be aware of when using Yaj SSE.

AJAX Fallback Limitations

No True Streaming

The AJAX fallback does not support true streaming like the native EventSource API. When using AJAX mode (either through forceAjax: true or when custom headers are set), the connection uses polling instead of a persistent connection.

Implication: Each request-response cycle completes before the next one begins.

Recommendation: Use the retry directive to control the polling frequency:

// Server side - set polling interval to 3 seconds
echo "retry: 3000\n";
echo "data: My Message\n";
echo "\n";
// Client side
var sse = new SSE('sse-server.php', {
options: {
forceAjax: true // Uses polling
},
onMessage: function(e) {
console.log(e.data);
}
});

Server-Side Considerations

When clients are using AJAX fallback, structure your server responses differently:

Don't do this (streaming multiple messages):

// This won't work well with AJAX fallback
while (true) {
echo "data: Message " . time() . "\n\n";
flush();
sleep(1);
}

Do this instead (single message per request):

// Better for AJAX fallback
echo "retry: 3000\n"; // Poll every 3 seconds
echo "data: Message " . time() . "\n";
echo "\n";

Custom Headers Force AJAX Mode

When you specify custom headers, Yaj SSE automatically uses AJAX mode because the native EventSource API doesn't support custom headers.

var sse = new SSE('sse-server.php', {
headers: {
'Authorization': 'Bearer token123'
},
// Even if forceAjax is false, AJAX mode will be used
onMessage: function(e) {
console.log(e.data);
}
});
cuidado

This happens automatically and silently. If you need custom headers (e.g., for authentication), be aware that you're using polling instead of streaming.

Browser Compatibility

Native EventSource Support

Most modern browsers support the native EventSource API:

  • Chrome 6+
  • Firefox 6+
  • Safari 5+
  • Edge (all versions)
  • Opera 11+

Internet Explorer: Does not support EventSource and will automatically use AJAX fallback.

Yaj Dependency

The AJAX fallback requires the Yaj library. If you're only targeting modern browsers and not using custom headers, you can use the native EventSource without the Yaj dependency.

Event ID Persistence

Last-Event-ID Header

The Last-Event-ID header is used to track which events have been received. This is handled automatically by:

  • Native EventSource (sent as HTTP header)
  • AJAX fallback (sent as custom header)

Server-Side Access

// Access the last event ID
$lastEventId = isset($_SERVER["HTTP_LAST_EVENT_ID"])
? intval($_SERVER["HTTP_LAST_EVENT_ID"])
: 0;

// Or from GET parameter (fallback)
if ($lastEventId == 0) {
$lastEventId = isset($_GET["lastEventId"])
? intval($_GET["lastEventId"])
: 0;
}

// Send new messages after this ID
$messages = getMessagesAfter($lastEventId);
foreach ($messages as $msg) {
echo "id: " . $msg['id'] . "\n";
echo "data: " . $msg['data'] . "\n";
echo "\n";
}

Connection Behavior

onOpen Event

The onOpen event fires only once per SSE instance, even if the connection reconnects:

var sse = new SSE('sse-server.php', {
onOpen: function(e) {
// Only fires on the first successful connection
console.log("Opened once");
}
});

This is by design to distinguish the initial connection from automatic reconnections.

Automatic Reconnection

Native EventSource automatically reconnects when the connection is lost. The AJAX fallback continues polling unless stop() is called.

CORS Considerations

For cross-origin requests, ensure your server sends appropriate CORS headers:

header("Access-Control-Allow-Origin: *");
// Or specific origin:
// header("Access-Control-Allow-Origin: https://yourdomain.com");

// If using custom headers:
header("Access-Control-Allow-Headers: Authorization, X-Custom-Header");
header("Access-Control-Allow-Methods: GET");
aviso

When using custom headers with cross-origin requests, browsers send a preflight OPTIONS request. Your server must handle this correctly.

Performance Considerations

Polling Frequency

When using AJAX fallback, balance between real-time updates and server load:

// More frequent = more real-time but higher load
echo "retry: 1000\n"; // Poll every 1 second

// Less frequent = lower load but less real-time
echo "retry: 5000\n"; // Poll every 5 seconds

Connection Limits

Browsers limit the number of concurrent connections per domain (typically 6). Each SSE connection counts toward this limit.

Impact: Having many SSE connections open can block other requests.

Recommendation: Limit the number of simultaneous SSE connections in your application.

References

For more information on Server-Sent Events: