LONK JSON WebSockets Protocol (LONK-WS)
LONK-WS is the protocol which ChRIS_ui uses to receive DICOM receive progress notifications from oxidicom.
The target audience of this page are ChRIS_ui developers.
CUBE subscribes to LONK messages and pushes them to ChRIS_ui. The data interchange is logcally the same as LONK, but is serialized as JSON and sent over WebSockets instead of a binary encoding over NATS.
binary JSON
[oxidicom] --------> [CUBE] -----------> [ChRIS_ui]
NATS WebSockets
Authentication and Initial Connection
First, the client (ChRIS_ui) opens a WebSocket connection with CUBE at the URI
api/v1/pacs/ws/?token=ABC123
where ABC123
is replaced with a JWT obtained from
api/v1/downloadtokens/
.
Subscription
Once connected, ChRIS_ui subscribes to notifications for DICOM series by sending to CUBE a SubscriptionRequest
in JSON:
{"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "action": "subscribe"}
And CUBE responds with a confirmation message (LonkWsSubscription
):
{"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "message": {"subscribed": true}}
Messages
All JSON messages from CUBE, besides the unsubscription response, will satisfy the type:
type LonkWsMessage = {
pacs_name: string;
SeriesInstanceUID: string;
message: LonkMessageData
}
Where LonkMessageData
is a union type with a variant corresponding to
each type of LONK message.
Name | Example |
---|---|
done | { "done": true } |
progress | { "ndicom": 2 } |
error | { "error": "stuck in chimney" } |
Complete Interaction
CUBE will send to the client at least 4 messages:
- subscription confirmed
- first
progress
, ndicom=1 - last
progress
, ndicom=N done
Notes
- There will usually be more
progress
messages between the first and the last. - The
progress
message for a series most recent to itsdone
message (i.e., the lastprogress
message) should be equal toNumberOfSeriesRelatedInstances
. - The value of
ndicom
will always increase.
Complete Interaction Example
--> {"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "action": "subscribe"}
<-- {"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "message": {"subscribed": true}}
<-- {"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "message": {"ndicom": 1}}
<-- {"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "message": {"ndicom": 9}}
<-- {"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "message": {"ndicom": 34}}
<-- {"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "message": {"ndicom": 108}}
<-- {"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "message": {"ndicom": 192}}
<-- {"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "message": {"done": true}}
Multiple Subscriptions
ChRIS_ui may subscribe to as many series as it wants to. Communication for [0, N) series are multiplexed over a single WebSocket connection.
For example, if you want notifications for all series of a study, the client needs to send multiple
SubscriptionRequest
.
{"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "action": "subscribe"}
{"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "action": "subscribe"}
Notifications for different series might be interleaved, e.g. messages from CUBE:
{"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "message": {"ndicom": 1}}
{"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "message": {"ndicom": 45}}
{"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.73667", "message": {"ndicom": 66}}
{"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "message": {"ndicom": 70}}
{"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.73667", "message": {"ndicom": 68}}
{"pacs_name": "MyPACS", "SeriesInstanceUID": "1.2.345.67890", "message": {"ndicom": 80}}
Unsubscribe
You can unsubscribe from all series notifications by sending a JSON message
{ "action": "unsubscribe" }
To which CUBE responds:
{ "message": { "subscribed": false } }