Skip to main content

LONK JSON WebSockets Protocol (LONK-WS)

LONK-WS is the protocol which ChRIS_ui uses to receive DICOM receive progress notifications from oxidicom.

tip

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.

NameExample
done{ "done": true }
progress{ "ndicom": 2 }
error{ "error": "stuck in chimney" }

Complete Interaction

CUBE will send to the client at least 4 messages:

  1. subscription confirmed
  2. first progress, ndicom=1
  3. last progress, ndicom=N
  4. done

Notes

  • There will usually be more progress messages between the first and the last.
  • The progress message for a series most recent to its done message (i.e., the last progress message) should be equal to NumberOfSeriesRelatedInstances.
  • 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 } }