Real-time updates

Real-time updates let review pages refresh key review activity without requiring a full page reload. The feature is optional, uses a WebSocket gateway behind Apache, and is designed to be additive to existing notification mechanisms.

If a reverse proxy, load balancer, or CDN sits in front of P4 Code Review, additional WebSocket proxy configuration might be required. See Real-time updates behind a reverse proxy or load balancer.

When enabled, P4 Code Review can push live updates to open review pages. Users can see changes such as review status updates, votes, reviewer changes, and CI-related activity as they happen.

  • The feature is opt-in.

  • It is purely additive.

  • Email, Slack, Jira, and other existing notification paths continue to work as before.

Before you begin

  • Confirm that your deployment already has a working P4 Code Review installation.

  • Confirm that Apache is the public entry point for the application.

  • Confirm that Redis and the queue worker are functioning normally.

  • Plan to verify both configuration and runtime state after enabling the feature.

After enabling the feature, always confirm that the WebSocket service is actually running.

On some installation paths, enablement does not guarantee that the service has started.

Enable real-time updates

Enable real-time updates using:

  • Standard configuration (config.php)

  • Docker

  • Installer-based enablement

  • Service check

Standard configuration

Enable the feature in config.php by setting notifications.websocket.enabled to true.

'notifications' => array(
			'websocket' => array(
			'enabled' => true,
			),
		),
Setting notifications.websocket.enabled = true enables the feature in P4 Code Review, but does not start the WebSocket gateway service.

The gateway service must also be enabled and started.

In most deployments, do not set server_url. The browser can use the same origin as the main P4 Code Review site and connect through /ws.

Docker

For Docker all-in-one deployments, use SWARM_WS_ENABLED when creating a fresh container. Existing containers may require recreation rather than an in-place toggle, depending on the shipped deployment path.

Installer-based enablement

Where supported by the packaged install flow, administrators can enable the feature through the installer path or by using configure-swarm.sh --enable-websocket.

Run configure-swarm.sh --enable-websocket to:

  • Sets the config flag.

  • Enables the service.

  • Starts the service.

Service check

After enabling the feature, verify that the WebSocket service is running.

  • DEB/RPM/tarball with systemd: Check systemctl status helix-swarm-websocket.

  • Docker: Check docker logs <container>.

Manual installations that enable the feature by editing config.php must also start the WebSocket service.

  • For fresh installations, enable and start the service:

    • systemctl enable --now helix-swarm-websocket
  • For upgrades, after adding the WebSocket configuration to config.php, start the service:

    • systemctl start helix-swarm-websocket

Configure Apache for /ws

The browser connects to the WebSocket gateway through Apache by using the /ws path. If Apache is not proxying this path correctly, the browser connection will not upgrade and live updates will not work.

The shipped Apache wiring should proxy only the exact /ws endpoint, strip client-supplied credential headers on that path, and explicitly use WebSocket proxying semantics.

Stock DEB and RPM installations proxy /ws using an inline configuration block in perforce-swarm-site.conf. These deployments do not typically use a separate Include statement for WebSocket proxy configuration.

HTTPS deployments, tarball deployments, and manually customized Apache configurations may instead use an included proxy configuration file such as apache-proxy.conf.

Confirm both of the following:

  • The WebSocket proxy configuration file is present.

  • The active Apache vhost includes that configuration.

Common symptom: If browser DevTools shows the WebSocket request as Finished instead of status 101, Apache is usually not proxying /ws correctly.

Apache verification

You can verify that Apache is correctly proxying the WebSocket endpoint by sending a WebSocket upgrade request to /ws. A correctly configured deployment returns HTTP status 101 Switching Protocols. HTTP 403 or 404 responses usually indicate that Apache is not proxying the endpoint correctly.

Origin allow-list

The WebSocket gateway validates the browser Origin header. In normal deployments, the allow-list is derived automatically from the configured external URL or hostname.

If users access P4 Code Review through a load balancer, CDN, or alternate hostname, make sure the deployment advertises the same external URL that users actually use. If these values do not match, the connection can be rejected even when the rest of the setup is correct.

The allow-list is derived from environment.external_url. If that setting is not present, the hostname is used.

Users must access P4 Code Review using the same URL configured for the deployment. For example, if the allow-list is derived from a hostname, accessingP4 Code Review by IP address can prevent live updates from working.

After changing the external URL, restart the WebSocket service:

systemctl restart helix-swarm-websocket

The derived allow-list can be confirmed from the gateway startup logs.

Multi-P4 Server deployments

Multi-P4 Server deployments work automatically. The gateway is server-agnostic and scopes delivery per connection.

  • There is no P4_SERVER_ID for administrators to configure.

  • There is no separate gateway process per P4 Server.

  • No per-server WebSocket routing configuration is required.

Load balancers and CDNs

If P4 Code Review is deployed behind a load balancer or CDN, configure Apache to restore the real client IP address by using mod_remoteip and a trusted proxy CIDR.

This matters because the WebSocket gateway applies per-IP limits. Without trusted proxy configuration, all clients can appear to come from the load balancer IP, which can cause connection caps to apply incorrectly.

Trust only the specific load-balancer or CDN address ranges that sit directly in front of P4 Code Review.

Real-time updates behind a reverse proxy or load balancer

The WebSocket gateway validates browser Origin headers.

'environment' => (
			'external_url' => 'https://YOUR-HOST',
		),

The value must match the URL that users enter in their browser to access P4 Code Review.

For information about Origin allow-lists and environment.external_url, see Origin allow-list.

Configure your front proxy

The front proxy must forward /ws as a WebSocket upgrade request.

If the proxy treats /ws as a normal HTTP request, the WebSocket connection fails and live updates do not work.

Apache example

Enable the required WebSocket proxy modules and add a dedicated /ws proxy rule.

Place the /ws rule before any catch-all proxy rules because Apache uses the first matching rule.

Copy
ProxyPass        /ws ws://BACKEND/ws upgrade=websocket
                ProxyPassReverse /ws ws://BACKEND/ws

                ProxyPass        / http://BACKEND/
            ProxyPassReverse / http://BACKEND/

nginx example

Configure a dedicated /ws location that forwards WebSocket upgrade headers:

Copy
location /ws {
                proxy_pass http://BACKEND/ws;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                }
            

The /ws rule must be evaluated before any catch-all proxy configuration.

All-in-one Docker behind your own proxy

In all-in-one Docker deployments, the container already includes the required internal WebSocket configuration.

If you place your own reverse proxy in front of the container:

  • Configure the outer proxy to forward /ws.

  • Configure server_url and external_url in the mounted config.php.

  • Do not edit the Apache configuration inside the container.

The Apache configuration packaged in the container is recreated when the container is replaced. Configuration changes made inside the container are not preserved. Make durable configuration changes in the outer proxy and in the mounted P4 Code Review configuration files.

Tarball deployments

Tarball deployments require manual setup for the WebSocket process and Apache wiring.

  • Configure the gateway under your chosen process manager.

  • Add the Apache /ws proxy block to the active vhost.

  • Enable the required Apache modules.

  • Verify both service startup and browser connectivity.

Tarball deployments should follow the same runtime checks and troubleshooting flow as packaged installs.

Ports and tuning

The WebSocket gateway uses two local ports:

  • WS_PORT: Gateway listen port, default 8080

  • HEALTH_PORT: Health endpoint port, default 9000

Both ports bind to loopback only. In the default deployment they are not exposed directly to users and do not require firewall changes, because Apache proxies browser traffic to the gateway through /ws.

Additional tuning controls include:

  • MAX_PENDING_AUTH

  • MAX_CONNS_PER_IP

  • MAX_ROOMS_PER_CLIENT

  • MAX_MSG_PER_SEC

  • MAX_TOTAL_CONNS

Most deployments should keep default values unless there is a measured scaling or abuse-control reason to change them.

Verify that it is working

Browser check

  1. Open a review page in the browser.

  2. Open browser DevTools and select the Network tab.

  3. Filter for WS.

  4. Look for the WebSocket connection on /ws.

  5. Confirm that the request shows status 101 and remains open.

  6. Open the Messages view and confirm that the browser sends an outbound authentication message and receives an inbound {"type":"system.connected"} message.

  7. From another browser session or another user session, make a review change such as a vote or state update.

  8. Confirm that a new frame arrives on the open WebSocket connection and the page updates without reload.

Server-side check

On systemd-based installs, tail the service log:

journalctl -u helix-swarm-websocket -f

As browsers connect, the service log should show client activity and the reported client count should rise.

Troubleshooting

Where to look

Install type Where to look Notes

DEB / RPM / tarball with systemd

journalctl -u helix-swarm-websocket -f

Primary live service log.

Docker all-in-one

docker logs <container>

Gateway lines are mixed with Apache and cron output; look for [server], [auth], and [health].

All install types

<data>/log-websocket

Persistent log file, rotated daily with the same logrotate policy as the main Swarm data log.

Symptom reference

Symptom Likely cause What to do

WebSocket request shows Finished and never reaches 101.

Apache is not proxying /ws.

Verify the WebSocket proxy configuration and confirm the include is present in the active vhost.

Status 101 succeeds but system.connected never arrives.

Gateway process needs restart after upgrade OR browser origin rejected by allow-list

Restart gateway. Verify external URL configuration. Check logs for ws_origin_rejected.

Run the following diagnostic command:

journalctl -u helix-swarm-websocket -f | grep ws_origin_rejected

Connection closes immediately with code 4001.

Origin not in allow-list.

Confirm that the external URL or hostname matches the public URL users actually use.

Auth succeeds but no real review events ever arrive.

Queue worker is not processing tasks.

Check queue health, queue cron state, and P4D health.

Browser tries to connect with ws:// from an HTTPS page.

TLS-terminating proxy is not preserving scheme correctly.

Set notifications.websocket.server_url to wss://... or fix X-Forwarded-Proto.

426 Upgrade Required when connecting through a reverse proxy.

The proxy is not forwarding /ws as a WebSocket upgrade request.

Configure the proxy to forward /ws as a WebSocket upgrade request. Verify that any dedicated /ws rule is evaluated before catch-all proxy rules.

The browser attempts to connect to ws://...:80 from an HTTPS page.

P4 Code Review does not know that the original request used HTTPS.

Configure notifications.websocket.server_url with a wss:// URL or configure the proxy to send X-Forwarded-Proto: https.

The WebSocket connection reaches status 101 but system.connected is never received.

The browser Origin is not included in the gateway allow-list.

Verify environment.external_url and ensure that users access P4 Code Review using the same public URL.

Network requirements, VPNs, proxies, and SSL inspection

In the default deployment, live updates do not require any VPN or firewall changes. The browser connects to the same host and port used for the main P4 Code Review site, typically wss://<p4-code-review-host>/ws.

Because the gateway listens on loopback and Apache proxies the request internally, there is no separate browser-facing WebSocket port in the standard configuration.

If users can already load the P4 Code Review web UI through the VPN, the WebSocket follows the same DNS, routing, and TLS path.

When proxies can block it

The main network failure mode is an intermediary that does not pass the HTTP upgrade handshake. This is most often caused by SSL-inspecting appliances or older forward proxies that do not support WebSocket upgrade cleanly.

If that happens:

  • Live updates fail to connect.

  • The rest of P4 Code Review continues to work normally.

  • Users can still refresh the page manually.

A VPN or firewall rule is needed only if an administrator deliberately overrides server_url to use a different host or port from the main P4 Code Review site.

Disable or roll back the real-time updates

You can disable real-time updates without affecting the rest of the product.

  • Set notifications.websocket.enabled = false

  • For Docker fresh-container workflows, use the appropriate SWARM_WS_ENABLED setting for the next container creation.

  • Or stop only the gateway service with systemctl stop helix-swarm-websocket

When the gateway is disabled:

  • REST API access continues to work.

  • Email notifications continue to work.

  • Jira integration continues to work.

  • Other P4 Code Review features continue to work.

  • Browsers show the live-updates connection as disconnected and recover automatically if the service returns.

Security in brief

  • Authentication uses a short-lived random token, not a password or JWT.

  • Tokens expire after about one hour and are revoked on logout.

  • Messages contain event metadata only, not review content.

  • Full data is still fetched through the authenticated REST API with normal ACL enforcement.

Expected outcome

In a correct deployment, administrators can enable live updates with minimal network impact, verify operation in both browser and service logs, and troubleshoot the feature using the same operational model already familiar from P4 Code Review and Apache.