Hello. This is a followup after my work with this. We implemented the code but ran into an issue with unprintable characters. We use wingding fonts for some of our data in tables. We could not figure out why messages with unprintable characters got lost in transmission and never got from the server to the client. It turns out that the issue is the fact that the "head" (header) variable was being created based on the size of the stream "before UTF8 conversion". So if the original data size was 500 characters, the header was indicating that the message size was 500. Then, as the data is read in chunks from the stream and the UTF8 conversion was done, there was one unprintable (char 252) that was in the data, causing the converted data size to be 501 characters which cause the message transmission to fail.
To address this, we had to delay the creation of the header until all of the data was read from the stream, UTF8 converted and save into a process private global. Once the entire stream was UTF8 translated into the PPG, we derived the new length of the data and then looped through the PPG and wrote everything to the websocket and that fixed the problem.
I am not thrilled with having to have the data go through two intermediate steps to get it from the dynamic object to the websocket, but, because the UTF8 conversion of unprintable characters, I saw no alternative.
Is there any chance there is another option that anyone is aware of that would allow me to determine the UTF8 character count of the stream without going through a process private global?
Thanks again for the continued support.
Here is a portion of the code from my writeStream method that deals with the new order of processing:
...
// Convert ASCII stream into UTF8 temp global
set streamSeq = 0
set dataLength = 0
while ('data.AtEnd) {
set bufferBlock = data.Read(.BUFSZ)
// Convert UTF8 if we aren't using Binary Web Sockets
if i%BinaryData '= 1 {
try {
set bufferBlock=$zconvert(bufferBlock,"O","UTF8")
} catch exp {
set bufferBlock=bufferBlock
}
}
set ^||streamData($i(streamSeq)) = bufferBlock
set dataLength = dataLength + $length(bufferBlock)
}
// Write header to the socket
if ((i%WSClassProtocolVersion > 1) && (i%WSDataFraming = 1)) {
set head = $ZLChar(dataLength)
if (i%BinaryData = 1) set head = head_"8"
else set head = head_"7"
} else {
set head = ""
}
write head
// Loop through temp global and write to the socket
set seq = 0
for {
set seq = $order(^||streamData(seq))
if (seq = "") { quit }
write ^||streamData(seq)
}
// Send a flush command now
write *-3
...