HL7-1: add documentation #4
4 changed files with 37 additions and 8 deletions
|
@ -19,13 +19,13 @@
|
|||
import { dev } from '$app/environment';
|
||||
|
||||
// connection state
|
||||
let ws = $state<WebSocket | undefined>(undefined);
|
||||
let ws = $state<WebSocket | undefined>(undefined); // websocket client
|
||||
let stationId = $state<string | undefined>(undefined); // stationId assigned by server
|
||||
let connectionState = $state<ConnectionState>(ConnectionState.disconnected);
|
||||
|
||||
// client state
|
||||
let composedMessage = $state('');
|
||||
let sentMessages = $state<ReceiveHl7v2Message[]>([]); // storing sent messages with client-timestamp for now
|
||||
let composedMessage = $state(''); // content of text-box
|
||||
let sentMessages = $state<ReceiveHl7v2Message[]>([]); // sent messages stored as type ReceiveHl7v2Message because of the timestamp
|
||||
let receivedMessages = $state<ReceiveHl7v2Message[]>([]);
|
||||
let isSending = $state(false);
|
||||
let copySuccess = $state(false);
|
||||
|
@ -60,6 +60,7 @@
|
|||
};
|
||||
const segmentTypes = Object.keys(segmentTemplates) as Array<keyof typeof segmentTemplates>;
|
||||
|
||||
// handles the connection process and message handling
|
||||
function connectToServer() {
|
||||
|
||||
console.log('Connecting to server...');
|
||||
|
@ -67,16 +68,20 @@
|
|||
|
||||
const socket = new WebSocket(`${dev ? 'ws' : 'wss'}://${env.PUBLIC_SERVER}`);
|
||||
|
||||
// store websocket on successful connection
|
||||
socket.onopen = () => {
|
||||
console.log('WebSocket connection established.');
|
||||
ws = socket;
|
||||
};
|
||||
|
||||
// register message handlers
|
||||
socket.onmessage = (event) => {
|
||||
|
||||
// parse every message as type Message
|
||||
const message = JSON.parse(event.data) as Message;
|
||||
console.log('Message received from server:', message);
|
||||
|
||||
// react based on message type
|
||||
switch (message.type) {
|
||||
|
||||
// initial message from server assigning ID
|
||||
|
@ -99,12 +104,14 @@
|
|||
}
|
||||
};
|
||||
|
||||
// reset connection state and websocket client on disconnect
|
||||
socket.onclose = () => {
|
||||
console.log('WebSocket connection closed.');
|
||||
connectionState = ConnectionState.disconnected;
|
||||
ws = undefined;
|
||||
};
|
||||
|
||||
// reset connection state and websocket client on error
|
||||
socket.onerror = (error) => {
|
||||
console.error('WebSocket error:', error);
|
||||
connectionState = ConnectionState.disconnected;
|
||||
|
@ -112,7 +119,7 @@
|
|||
};
|
||||
}
|
||||
|
||||
// clean up on close
|
||||
// reset connection state and websocket client on tab closed
|
||||
$effect(() => {
|
||||
return () => {
|
||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||
|
@ -122,21 +129,26 @@
|
|||
};
|
||||
});
|
||||
|
||||
// adds the template of the provided segment type at the bottom of the textbox
|
||||
function addSegment(type: keyof typeof segmentTemplates) {
|
||||
const template = segmentTemplates[type].template();
|
||||
composedMessage += `\r\n${template}`;
|
||||
}
|
||||
|
||||
// handles sending a message to the websocket server
|
||||
function handleSendMessage(message: string) {
|
||||
|
||||
// check for active connection
|
||||
if (!ws || ws.readyState !== WebSocket.OPEN || isSending || !stationId) {
|
||||
console.log('Socket not ready');
|
||||
return;
|
||||
}
|
||||
|
||||
// set UI state
|
||||
isSending = true;
|
||||
deliveryError = '';
|
||||
|
||||
// construct Message object and send it
|
||||
const messageToSend = {
|
||||
type: 'send_hl7v2',
|
||||
payload: { message },
|
||||
|
@ -148,9 +160,12 @@
|
|||
payload: { message, timestamp: new Date().toISOString() },
|
||||
} as ReceiveHl7v2Message, ...sentMessages];
|
||||
composedMessage = segmentTemplates.MSH.template();
|
||||
|
||||
// reset UI state
|
||||
isSending = false;
|
||||
}
|
||||
|
||||
// copies the stationId to the clipboard and handles UI state
|
||||
function copyStationId() {
|
||||
if (stationId) {
|
||||
navigator.clipboard.writeText(stationId).then(() => {
|
||||
|
@ -163,6 +178,7 @@
|
|||
</script>
|
||||
|
||||
|
||||
<!-- 'component' for displaying a message in the message lists (sent and received) -->
|
||||
{#snippet message(msg: ReceiveHl7v2Message)}
|
||||
<div class="bg-foreground/10 p-3 rounded-md space-y-1">
|
||||
<p class="text-xs">{new Date(msg.payload.timestamp).toLocaleString()}</p>
|
||||
|
|
|
@ -1,23 +1,25 @@
|
|||
|
||||
// define available configurations
|
||||
interface Config {
|
||||
port: number;
|
||||
prefixes: string[];
|
||||
poolSize: number;
|
||||
}
|
||||
|
||||
// construct config object from environment variables
|
||||
export const config: Config = {
|
||||
port: parseInt(process.env.PORT || '8080', 10),
|
||||
prefixes: (process.env.PREFIXES || 'STA').split(","),
|
||||
poolSize: parseInt(process.env.POOL_SIZE || '100', 10),
|
||||
};
|
||||
|
||||
// validate config
|
||||
if (isNaN(config.port) || config.port < 1024 || config.port > 49151) {
|
||||
throw new Error('Invalid PORT environment variable (1024 - 49151)');
|
||||
}
|
||||
|
||||
if (config.prefixes.length === 0) {
|
||||
throw new Error('Invalid PREFIXES environment variable (length > 1)');
|
||||
}
|
||||
|
||||
if (isNaN(config.poolSize) || config.poolSize < config.prefixes.length) {
|
||||
throw new Error('Invalid PORT environment variable (poolSize >= prefix.length)');
|
||||
throw new Error('Invalid pool size environment variable (poolSize >= prefix.length)');
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ for (const prefix of config.prefixes) {
|
|||
}
|
||||
}
|
||||
|
||||
// mixes the array randomly to avoid getting the same ID reassigned
|
||||
function shake(arr: any[]) {
|
||||
for (let i = arr.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
|
@ -71,9 +72,11 @@ wss.on('connection', (ws) => {
|
|||
|
||||
console.log(`Client connected. Assigning ID: ${stationId}`);
|
||||
|
||||
// listen for messages and defined message handling
|
||||
ws.on('message', (message) => {
|
||||
try {
|
||||
|
||||
// parse every message to type Message
|
||||
const parsedMessage: Message = JSON.parse(message.toString());
|
||||
console.log(`Received message from ${stationId}:`, parsedMessage);
|
||||
|
||||
|
@ -81,6 +84,7 @@ wss.on('connection', (ws) => {
|
|||
if (parsedMessage.type === MessageType.send_hl7v2) {
|
||||
|
||||
const { message } = parsedMessage.payload;
|
||||
|
||||
// TODO: validate message
|
||||
|
||||
// get sender and recipient ID
|
||||
|
@ -98,6 +102,7 @@ wss.on('connection', (ws) => {
|
|||
// Find the recipient's WebSocket connection in our map.
|
||||
const recipientWs = clients.get(recipientId);
|
||||
|
||||
// check if recipient exists and is connected
|
||||
if (recipientWs && recipientWs.readyState === WebSocket.OPEN) {
|
||||
|
||||
// The recipient is connected. Forward the message.
|
||||
|
@ -136,6 +141,7 @@ wss.on('connection', (ws) => {
|
|||
if (stationId) {
|
||||
availableIds.push(stationId);
|
||||
}
|
||||
// shake IDs to avoid getting the same ID reassigned
|
||||
availableIds = shake(availableIds);
|
||||
});
|
||||
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
|
||||
// defines different connection states
|
||||
export enum ConnectionState {
|
||||
connecting = 'connecting',
|
||||
connected = 'connected',
|
||||
disconnected = 'disconnected',
|
||||
}
|
||||
|
||||
// defines message types
|
||||
export enum MessageType {
|
||||
assign_id = 'assign_id',
|
||||
send_hl7v2 = 'send_hl7v2',
|
||||
|
@ -11,10 +14,12 @@ export enum MessageType {
|
|||
delivery_error = 'delivery_error',
|
||||
}
|
||||
|
||||
// defines body of message types
|
||||
export type Message =
|
||||
| { type: MessageType.assign_id, payload: { stationId: string }}
|
||||
| { type: MessageType.send_hl7v2, payload: { message: string }}
|
||||
| { type: MessageType.receive_hl7v2, payload: { message: string, timestamp: string }}
|
||||
| { type: MessageType.delivery_error, payload: { error: string }}
|
||||
|
||||
// required to define list of this message type
|
||||
export type ReceiveHl7v2Message = Extract<Message, { type: MessageType.receive_hl7v2 }>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue