Repository: symfony/symfony
File: src/Symfony/Component/HttpFoundation/EventStreamResponse.php (PHP)

Code before:
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

/**
 * Represents a streaming HTTP response for sending server events
 * as part of the Server-Sent Events (SSE) streaming technique.
 *
 * @see ServerEvent
 *
 * @author Yonel Ceruto <open@yceruto.dev>
 *
 * Example usage:
 *
 *     return new EventStreamResponse(function () {
 *         while (true) {
 *             yield new ServerEvent(time(), type: 'ping');
 *
 *             if (connection_aborted()) {
 *                 break;
 *             }
 *
 *             sleep(1);
 *         }
 *     });
 */
class EventStreamResponse extends StreamedResponse
{
    /**
     * @param int $retry The event reconnection time in milliseconds
     */
    public function __construct(?callable $callback = null, int $status = 200, array $headers = [], private int $retry = 0)
    {
        $headers += [
            'Content-Type' => 'text/event-stream',
            'Cache-Control' => 'no-cache',
            'Connection' => 'keep-alive',
        ];

        parent::__construct($callback, $status, $headers);
    }

    public function setCallback(callable $callback): static
    {
        if ($this->callback) {
            return parent::setCallback($callback);

Review comment (suggestion):
We could make this check inside `EventStreamResponse` to reduce the code needed to implement an event stream.

Code after:
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\HttpFoundation;

/**
 * Represents a streaming HTTP response for sending server events
 * as part of the Server-Sent Events (SSE) streaming technique.
 *
 * To broadcast events to multiple users at once, for long-running
 * connections and for high-traffic websites, prefer using the Mercure
 * Symfony Component, which relies on Software designed for these use
 * cases: https://symfony.com/doc/current/mercure.html
 *
 * @see ServerEvent
 *
 * @author Yonel Ceruto <open@yceruto.dev>
 *
 * Example usage:
 *
 *     return new EventStreamResponse(function () {
 *         yield new ServerEvent(time());
 *
 *         sleep(1);
 *
 *         yield new ServerEvent(time());
 *     });
 */
class EventStreamResponse extends StreamedResponse
{
    /**
     * @param int|null $retry The number of milliseconds the client should wait
     *                        before reconnecting in case of network failure
     */
    public function __construct(?callable $callback = null, int $status = 200, array $headers = [], private ?int $retry = null)
    {
        $headers += [
            'Connection' => 'keep-alive',
            'Content-Type' => 'text/event-stream',
            'Cache-Control' => 'private, no-cache, no-store, must-revalidate, max-age=0',
            'X-Accel-Buffering' => 'no',
            'Pragma' => 'no-cache',
            'Expire' => '0',
        ];

        parent::__construct($callback, $status, $headers);
    }