Extend the transit/JSON content negotiation to the WebSocket
notifications endpoint (/ws/notifications). The format is
negotiated once on the upgrade request (Accept header or
_fmt=json query parameter, same rules as the rest of the RPC
API) and applies bidirectionally: outbound notification
messages are encoded with the negotiated encoder and inbound
client messages are decoded accordingly.
The generic websocket protocol implementation now accepts
encode/decode functions as listener options, defaulting to
the historical transit encoding. A small normalization step
converts JSON decoded messages (:type to keyword and entity
ids to UUID objects) into the same shape produced by transit.
Closes#11409
AI-assisted-by: glm-5.3-flash