feat(ocpp): 添加对WebSocket子协议的支持和缺失参数检查

This commit is contained in:
2026-03-15 03:41:38 +08:00
parent b45896a9dd
commit 216a8e118d
3 changed files with 34 additions and 5 deletions

View File

@@ -85,8 +85,12 @@ app.get(
'/ocpp/:chargePointId',
upgradeWebSocket((c) => {
const chargePointId = c.req.param('chargePointId')
if (!chargePointId) {
throw new Error('Missing chargePointId route param')
}
const connInfo = getConnInfo(c)
return createOcppHandler(chargePointId, connInfo.remote.address)
const requestedProtocol = c.req.header('sec-websocket-protocol')
return createOcppHandler(chargePointId, connInfo.remote.address, requestedProtocol)
}),
)

View File

@@ -92,6 +92,26 @@ function sendCallError(
)
}
function pickOcppSubprotocol(
negotiatedProtocol?: string | null,
requestedHeader?: string | null,
) {
if (negotiatedProtocol && isSupportedOCPP(negotiatedProtocol)) {
return negotiatedProtocol
}
if (!requestedHeader) {
return null
}
const requestedProtocols = requestedHeader
.split(',')
.map((value) => value.trim())
.filter(Boolean)
return requestedProtocols.find((protocol) => isSupportedOCPP(protocol)) ?? null
}
/**
* Factory that produces a hono-ws event handler object for a single
* OCPP WebSocket connection.
@@ -99,7 +119,11 @@ function sendCallError(
* Usage in route:
* upgradeWebSocket((c) => createOcppHandler(c.req.param('chargePointId'), remoteAddr))
*/
export function createOcppHandler(chargePointIdentifier: string, remoteAddr?: string) {
export function createOcppHandler(
chargePointIdentifier: string,
remoteAddr?: string,
requestedProtocolHeader?: string,
) {
const ctx: OcppConnectionContext = {
chargePointIdentifier,
isRegistered: false,
@@ -107,14 +131,14 @@ export function createOcppHandler(chargePointIdentifier: string, remoteAddr?: st
return {
onOpen(_evt: Event, ws: WSContext) {
const subProtocol = ws.protocol ?? 'unknown'
if (!isSupportedOCPP(subProtocol)) {
const subProtocol = pickOcppSubprotocol(ws.protocol, requestedProtocolHeader)
if (!subProtocol) {
ws.close(1002, 'Unsupported subprotocol')
return
}
ocppConnections.set(chargePointIdentifier, ws)
console.log(
`[OCPP] ${chargePointIdentifier} connected` +
`[OCPP] ${chargePointIdentifier} connected (${subProtocol})` +
(remoteAddr ? ` from ${remoteAddr}` : ''),
)
},