OCPP: keep websocket alive between heartbeats (#33099)

This commit is contained in:
andig 2026-08-23 11:16:44 +02:00 • committed by GitHub
parent 83d322b5e9
commit af4d14f65c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 16 additions and 1 deletions

View file

@ -4,6 +4,14 @@ import "time"
var Timeout = time.Minute // default request / response timeout on protocol level
const (
heartbeatInterval = time.Minute // heartbeat interval requested in BootNotification
// pingWait must exceed heartbeatInterval, otherwise chargers not sending
// websocket pings are disconnected while idle
pingWait = 3 * heartbeatInterval
)
// TriggerBootDelay defines how long to wait after WebSocket connect before
// proactively triggering a BootNotification. This allows the connection to
// stabilize and gives the charger a chance to send a spontaneous BootNotification.

View file

@ -16,7 +16,7 @@ var (
func (cp *CP) OnBootNotification(request *core.BootNotificationRequest) (*core.BootNotificationConfirmation, error) {
res := &core.BootNotificationConfirmation{
CurrentTime: types.Now(),
Interval: 60,
Interval: int(heartbeatInterval.Seconds()),
Status: core.RegistrationStatusAccepted,
}

View file

@ -28,6 +28,9 @@ func TestBootNotificationStoresResultAndConnects(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, core.RegistrationStatusAccepted, res.Status)
// heartbeat must stay below the websocket inactivity timeout
assert.Less(t, time.Duration(res.Interval)*time.Second, pingWait)
// should be connected after BootNotification
assert.True(t, cp.Connected(), "should be connected after BootNotification")
assert.Equal(t, bootReq, cp.BootNotificationResult, "should store boot result")

View file

@ -140,6 +140,10 @@ func NewServer(cfg Config, networkExternalUrl string) {
server := &interceptingServer{Server: ws.NewServer()}
server.SetCheckOriginHandler(func(r *http.Request) bool { return true })
timeouts := ws.NewServerTimeoutConfig()
timeouts.PingWait = pingWait
server.SetTimeoutConfig(timeouts)
dispatcher := ocppj.NewDefaultServerDispatcher(ocppj.NewFIFOQueueMap(0))
endpoint := ocppj.NewServer(server, dispatcher, nil, core.Profile, remotetrigger.Profile, smartcharging.Profile, security.Profile, firmware.Profile)