Skip to content
OCPP WebSocket Communication: A Developer's Guide

OCPP WebSocket Communication: A Developer's Guide

·9 min read
Share:

OCPP WebSocket communication is the transport layer that enables real-time, bidirectional messaging between EV chargers and their Central System (CSMS). Unlike traditional REST APIs where the client polls for updates, WebSocket maintains a persistent connection — allowing either side to send messages at any time without the overhead of repeated HTTP handshakes.

Understanding how OCPP uses WebSocket is essential for every developer building or integrating with EV charging infrastructure. Most OCPP bugs in production trace back to WebSocket-level issues: connection drops, message ordering problems, or security misconfigurations.

Why OCPP Uses WebSocket

OCPP chose WebSocket over alternatives for specific technical reasons:

  • Bidirectional: Both the charger and CSMS can initiate messages. The CSMS needs to send commands (RemoteStart, Reset) to chargers without the charger polling for them
  • Persistent: A single TCP connection stays open for hours or days, eliminating reconnection overhead
  • Low latency: Messages arrive in milliseconds, critical for real-time operations like smart charging profile updates
  • Firewall friendly: WebSocket upgrades from HTTP, traversing corporate firewalls and proxies that block raw TCP
  • Lightweight: Minimal framing overhead compared to HTTP request/response cycles

OCPP 1.6 supports both WebSocket (JSON) and SOAP. OCPP 2.0.1 uses WebSocket exclusively, having dropped SOAP support entirely.

Connection Lifecycle

1. WebSocket Handshake

The charge point initiates a WebSocket connection to the CSMS. The URL follows a specific pattern:

ws://csms.example.com/ocpp/CP001
wss://csms.example.com/ocpp/CP001

The path typically includes the charge point identity (CP001). The CSMS uses this to identify which charger is connecting.

The HTTP upgrade request includes OCPP-specific subprotocols:

GET /ocpp/CP001 HTTP/1.1
Host: csms.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Protocol: ocpp1.6, ocpp2.0.1
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==

The CSMS responds with the selected subprotocol:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Protocol: ocpp1.6

2. BootNotification

Immediately after the WebSocket connection is established, the charge point sends a BootNotification message:

[2, "19223201", "BootNotification", {
  "chargePointVendor": "EVManufacturer",
  "chargePointModel": "FastCharger-50",
  "chargePointSerialNumber": "SN-001234",
  "firmwareVersion": "3.2.1"
}]

The CSMS responds with the registration status and heartbeat interval:

[3, "19223201", {
  "status": "Accepted",
  "currentTime": "2025-02-13T10:00:00.000Z",
  "interval": 300
}]

3. Normal Operation

Once registered, the charge point and CSMS exchange messages for charging operations, status updates, and remote commands. The connection remains open indefinitely.

4. Disconnection and Reconnection

When the connection drops (network failure, CSMS restart, charger power cycle), the charge point is responsible for reconnecting. The CSMS must restore the charger's state from the last known information.

OCPP JSON Message Format

OCPP defines three message types, all transmitted as JSON arrays over WebSocket:

CALL (Message Type 2)

A request message sent by either party. Format:

[2, "uniqueMessageId", "ActionName", {payload}]

Example — Charger sends StatusNotification:

[2, "msg-4501", "StatusNotification", {
  "connectorId": 1,
  "errorCode": "NoError",
  "status": "Charging",
  "timestamp": "2025-02-13T10:15:00.000Z"
}]

Example — CSMS sends RemoteStartTransaction:

[2, "cmd-7890", "RemoteStartTransaction", {
  "connectorId": 1,
  "idTag": "RFID-ABC123"
}]

CALLRESULT (Message Type 3)

A successful response to a CALL. The message ID must match the original CALL:

[3, "uniqueMessageId", {payload}]

Example — CSMS responds to StatusNotification:

[3, "msg-4501", {}]

Example — Charger responds to RemoteStartTransaction:

[3, "cmd-7890", {
  "status": "Accepted"
}]

CALLERROR (Message Type 4)

An error response to a CALL. Used when the message cannot be processed:

[4, "uniqueMessageId", "errorCode", "errorDescription", {errorDetails}]

Example — Unknown action error:

[4, "msg-9999", "NotImplemented",
  "This action is not supported",
  {}]

Standard OCPP Error Codes

Error Code Meaning
NotImplemented Requested action is not known or supported
NotSupported Action is recognized but not supported
InternalError Internal error in the receiver
ProtocolError Payload does not conform to protocol
SecurityError Security issue (e.g., invalid certificate)
FormationViolation Payload is syntactically incorrect
PropertyConstraintViolation Property value violates constraints
OccurrenceConstraintViolation Required property is missing
TypeConstraintViolation Property has wrong type
GenericError Catch-all for other errors

Heartbeat Mechanism

The Heartbeat message serves two purposes: confirming the charge point is still connected, and synchronizing its clock with the CSMS.

[2, "hb-001", "Heartbeat", {}]
[3, "hb-001", {
  "currentTime": "2025-02-13T10:05:00.000Z"
}]

The heartbeat interval is set by the CSMS in the BootNotification response (typically 60-300 seconds). If the CSMS does not receive a heartbeat within the expected window, it should consider the charge point offline.

Important implementation details:

  • Any OCPP message resets the heartbeat timer — if a charger sends MeterValues, it does not need to send a separate Heartbeat until the next interval
  • The CSMS should allow some tolerance (e.g., 2x the interval) before marking a charger offline, accounting for network jitter
  • Charge points should use the currentTime from the response to correct clock drift

Reconnection Strategies

Network disconnections are inevitable. A robust OCPP implementation needs a reliable reconnection strategy.

Exponential Backoff

The recommended approach for charge point reconnection:

Attempt 1: Wait 1 second
Attempt 2: Wait 2 seconds
Attempt 3: Wait 4 seconds
Attempt 4: Wait 8 seconds
...
Maximum: Wait 300 seconds (5 minutes)

Adding random jitter (0-30% of the wait time) prevents the "thundering herd" problem — where hundreds of chargers reconnect simultaneously after a CSMS restart.

CSMS-Side Reconnection Handling

When a charge point reconnects, the CSMS must:

  1. Accept the new WebSocket connection
  2. Process the BootNotification (may return Accepted or Pending)
  3. Request current status via TriggerMessage for StatusNotification
  4. Reconcile any transactions that were active during disconnection
  5. Re-apply any pending charging profiles or configuration changes

Connection Monitoring

Strategy Implementation Typical Interval
OCPP Heartbeat Application-level ping 60-300 seconds
WebSocket Ping/Pong Protocol-level keepalive 30-60 seconds
TCP Keepalive OS-level connection check 60-120 seconds
Load Balancer Health Check Infrastructure-level 10-30 seconds

Use multiple layers. WebSocket Ping/Pong detects dead connections faster than OCPP Heartbeat, while TCP Keepalive catches cases where both endpoints think the connection is alive but an intermediate device has dropped it.

Security: TLS and WSS

Production OCPP deployments must use encrypted WebSocket connections (WSS — WebSocket Secure):

OCPP Security Profiles

Profile Authentication Encryption OCPP Version
Profile 1 HTTP Basic Auth None — unencrypted (ws://) 1.6, 2.0.1
Profile 2 HTTP Basic Auth TLS with server certificate (wss://) 1.6, 2.0.1
Profile 3 TLS client certificate (mutual auth) TLS with client + server certificates (wss://) 2.0.1

Note: OCPP 1.6 deployments without any security profile configured use plain WebSocket (ws://) with no authentication. OCPP 2.0.1 requires at minimum Profile 1.

TLS Implementation Checklist

  • Use TLS 1.2 or higher (TLS 1.3 preferred)
  • Validate server certificates on the charge point side
  • For Profile 3, manage client certificate provisioning and rotation
  • Pin certificates or use a dedicated CA for your charging network
  • Configure cipher suites to exclude weak algorithms (no RC4, no 3DES)
  • Handle certificate expiration gracefully with automated renewal

Debugging WebSocket Issues

Common Problems and Solutions

Connection refused: The CSMS is not listening on the expected port or the charge point URL path is incorrect. Verify the WebSocket endpoint URL and that the subprotocol header matches.

Connection drops after 60 seconds: A load balancer or proxy is closing idle connections. Ensure WebSocket Ping/Pong frames are being sent, or configure the infrastructure to allow long-lived connections.

Messages not received: Check that both sides handle WebSocket fragmentation correctly. Some OCPP libraries buffer incomplete frames, and large messages (like firmware update notifications) may be split across multiple WebSocket frames.

Authentication failures: Verify that HTTP Basic Auth credentials or TLS client certificates are correctly configured. Check certificate chain completeness — intermediate CA certificates are a frequent omission.

Message ordering issues: OCPP requires that a CALL is answered before the next CALL is sent in the same direction. However, both the charger and CSMS can each have one outstanding CALL simultaneously — one in each direction. Sending a second CALL in the same direction before receiving a response to the first causes undefined behavior.

Testing WebSocket Communication with OCPPLab

Debugging WebSocket issues with physical chargers is time-consuming — you cannot easily inspect what the charger is sending, inject specific errors, or reproduce timing-sensitive bugs.

OCPPLab provides full visibility into OCPP WebSocket communication:

  • Message Inspector: View every WebSocket frame with exact timestamps, including Ping/Pong
  • Connection Simulation: Test reconnection scenarios, slow networks, and connection drops
  • Error Injection: Send malformed JSON, unknown actions, or out-of-sequence messages to test CSMS error handling
  • Security Profile Testing: Validate all OCPP security profiles including TLS client certificate authentication
  • Multi-Connection Load: Open hundreds of simultaneous WebSocket connections to stress-test your CSMS

Whether you are debugging a single charger's connection issue or validating that your CSMS handles 5,000 concurrent WebSocket connections, OCPPLab gives you the control and visibility that physical hardware cannot.

Frequently Asked Questions

Can OCPP work over HTTP instead of WebSocket?

OCPP 1.6 also has a SOAP variant (OCPP 1.6S), but it is legacy and rarely used in new deployments. OCPP 2.0.1 requires WebSocket exclusively. WebSocket is strongly recommended for all new implementations because it enables server-initiated messages (which HTTP cannot do without polling).

How many WebSocket connections can a CSMS handle?

This depends entirely on the CSMS architecture. A well-optimized CSMS on modern infrastructure can handle 10,000-100,000 concurrent WebSocket connections. The bottleneck is typically database writes (MeterValues), not the WebSocket connections themselves.

What happens to active transactions when WebSocket disconnects?

The charge point continues charging locally. Transaction data (MeterValues) is typically queued and sent after reconnection. The CSMS should detect the disconnection and await reconnection, then reconcile any missed data. OCPP 2.0.1 handles this more gracefully than 1.6 with its improved transaction model.

Should I use a WebSocket library or implement the protocol myself?

Always use an established WebSocket library. Implementing the WebSocket protocol from scratch introduces unnecessary risk. For OCPP specifically, use an OCPP library that handles message routing, ID generation, and timeout management on top of the WebSocket layer.

How do I handle WebSocket connections behind a load balancer?

Use sticky sessions (session affinity) to ensure a charge point always connects to the same CSMS instance, or implement a shared session store. The load balancer must support WebSocket upgrade and long-lived connections. Configure appropriate idle timeout values to prevent premature disconnection.

Last updated:

Test your OCPP implementation today

Deploy 1000+ virtual charge points in minutes. No hardware needed.

Get OCPP & EV charging insights

Protocol updates, testing best practices, and industry news. No spam.

Join 1,000+ developers testing with us

Stop Paying for Hardware You Don't Need

Deploy 10,000 virtual chargers in 2 minutes. Catch bugs before production, cut months from QA cycles, and save 80% on testing infrastructure.

Simulate vendors
Emulate ABB, EVBox, Wallbox and more with realistic firmware behaviors.
Test at scale
Run hundreds of virtual points to validate performance and autoscaling.
Integrate safely
Verify edge-cases, firmware updates, and recovery flows before field deployment.
No credit card required • Deploy your first virtual charger in 2 minutes • Contact sales for enterprise plans