Love Zhaoying Posted February 15, 2023 Share Posted February 15, 2023 I know this general question came up before, but I have forgotten the answer. When sending messages to other users or yourself with llSay(), occasionally the messages are displayed out of order in the viewer. Are messages "guaranteed" to be sent and received between scripts in the intended order? I will be using llRegionSayTo() to send messages between two scripts. Thanks, Love Link to comment Share on other sites More sharing options...
Quistess Alpha Posted February 15, 2023 Share Posted February 15, 2023 (edited) AFAIK, no. if sending large amounts of data in 1024 length packets (as you alluded to in another post) and you really need to keep the order, you might have to add some book-keeping to your conversation protocol. For example "0,some data","1,some data","-2,some data" using the sign to indicate it's the last transmission in the group, receiver stores everything and interprets only after a negative index, and number_of_received_packets+1==llAbs(the_last_negative_index). sending acknowledgements from the receiving object, (transmitter 'sends the next packet' when it hears "ack" from the receiver) if it's not mission critical, llSleep(0.2); between each message is probably good enough for most use-cases) Edited February 15, 2023 by Quistess Alpha 1 Link to comment Share on other sites More sharing options...
Love Zhaoying Posted February 15, 2023 Author Share Posted February 15, 2023 (edited) 23 minutes ago, Quistess Alpha said: AFAIK, no. if sending large amounts of data in 1024 length packets (as you alluded to in another post) and you really need to keep the order, you might have to add some book-keeping to your conversation protocol. For example "0,some data","1,some data","-2,some data" using the sign to indicate it's the last transmission in the group, receiver stores everything and interprets only after a negative index, and number_of_received_packets+1==llAbs(the_last_negative_index). sending acknowledgements from the receiving object, (transmitter 'sends the next packet' when it hears "ack" from the receiver) if it's not mission critical, llSleep(0.2); between each message is probably good enough for most use-cases) Actually, it's less about keeping the 1024-byte packets in order (one way of looking at it), then making sure the "tail bits" (the parts that were > 1024) get delivered AFTER the 1024 bits. But then again, if your entire message is "multiples of 1024" for a single unit of data, then you still have to track which "chunk" it was to reassemble it all. 23 minutes ago, Quistess Alpha said: sending acknowledgements from the receiving object, (transmitter 'sends the next packet' when it hears "ack" from the receiver) ^^The most straightforward method.. Luckily, the "process" of send/receive/acknowledge is literally separated from the main "process" due to the magic of LSD so...using ACK/NAK won't kill it. Mostly. I was thinking about the other option, let the packets get there in random order with index information: "Here is a packet with LSD Key Blah, value Foo, this is Packet 3 of 5 packets for this Key". So, the Receiver would be able to hold all the packets and reassemble them once all 5 were received. This may be a little faster than the ACK/NAK solution, since the Sender would not wait for an ACK before sending the next packet. In case I left the use-case out, this is for sending LSD data from one object to another. ETA: Darn, I was hoping the "out of order delivery" issue was really just an artifact of "things said on Channel 0". Edited February 15, 2023 by Love Zhaoying Link to comment Share on other sites More sharing options...
Quistess Alpha Posted February 15, 2023 Share Posted February 15, 2023 (edited) 23 minutes ago, Love Zhaoying said: In case I left the use-case out, this is for sending LSD data from one object to another. If I needed to do that, I've tossed around the idea of linking and breaking in my head a few times, but not actually tried it. that requires special permissions and is a tad slow though. Edited February 15, 2023 by Quistess Alpha 1 Link to comment Share on other sites More sharing options...
Love Zhaoying Posted February 15, 2023 Author Share Posted February 15, 2023 7 minutes ago, Quistess Alpha said: If I needed to do that, I've tossed around the idea of linking and breaking in my head a few times, but not actually tried it. that requires special permissions and is a tad slow though. The "backup disk" will be a HUD, as will the main object. Neither will be linked. That's the idea so far! Link to comment Share on other sites More sharing options...
Quistess Alpha Posted February 15, 2023 Share Posted February 15, 2023 10 minutes ago, Love Zhaoying said: The "backup disk" will be a HUD, as will the main object. Neither will be linked. I usually figure out the technicals before deciding on the UI. probably too much hassle if you're only slightly over 1024, but having the object rez and then link the "backup disk" then unlink it and present it to the user to take, doesn't sound too unfriendly, especially if actually using the backup is less common than creating one. . .now I think on it though, scripted backup seems pretty silly unless the object is no-copy. Link to comment Share on other sites More sharing options...
Love Zhaoying Posted February 15, 2023 Author Share Posted February 15, 2023 5 minutes ago, Quistess Alpha said: 21 minutes ago, Love Zhaoying said: The "backup disk" will be a HUD, as will the main object. Neither will be linked. I usually figure out the technicals before deciding on the UI. probably too much hassle if you're only slightly over 1024, but having the object rez and then link the "backup disk" then unlink it and present it to the user to take, doesn't sound too unfriendly, especially if actually using the backup is less common than creating one. . .now I think on it though, scripted backup seems pretty silly unless the object is no-copy. Yeah, I figured out this technical approach long ago with many many notes and some tests, I'm just finally remembering that llRegionSayTo() had the limit of 1024! Since the use-case, backing up / saving / restoring LSD data requires two objects that are NOT linked (since each have their own LSD storage), llReionSayTo() was the natural choice. I just happened to decide on a HUD for both the "disk" and the "master" for now. Link to comment Share on other sites More sharing options...
Quistess Alpha Posted February 15, 2023 Share Posted February 15, 2023 1 hour ago, Love Zhaoying said: Since the use-case, backing up / saving / restoring LSD data requires two objects that are NOT linked my point was that, if you link them, the LSD becomes merged, which if you figure out the caveats, might bypass the need for communication. Link to comment Share on other sites More sharing options...
Love Zhaoying Posted February 15, 2023 Author Share Posted February 15, 2023 Just now, Quistess Alpha said: 1 hour ago, Love Zhaoying said: Since the use-case, backing up / saving / restoring LSD data requires two objects that are NOT linked my point was that, if you link them, the LSD becomes merged, which if you figure out the caveats, might bypass the need for communication. I definitely don't want to "go there" this time around, at least! 🙂 Related: I learned awhile ago that if you hack 2 LSL JSON strings together, any "duplicate" keys in the last part of the string "win" (without any errors due to duplicate issues, JSON invalid errors, etc.). You have to actually "change" something in the final Json then it clear out the older duplicate dups. I decided NOT to use that hack, as using higher-level LSD KVP's solved the problem much better. After THAT experience, I don't want to worry whether LSD object merging suits my needs or not. Because I want it to work "this" way * pointing * 1 Link to comment Share on other sites More sharing options...
Love Zhaoying Posted February 15, 2023 Author Share Posted February 15, 2023 FYI, spent a couple hours coming up with a scheme for the whole "send command / with a KVP", "send partial KVP", etc. So, it will work out. When plans get this far, they always do - even if they get changed completely later! Link to comment Share on other sites More sharing options...
Love Zhaoying Posted February 15, 2023 Author Share Posted February 15, 2023 I had the thought: you could implement a full XMODEM, YMODEM, or ZMODEM protocol between objects, and it would be faster than old analog over-the POTS (plain old telephone system) modem transfers! Link to comment Share on other sites More sharing options...
Wulfie Reanimator Posted February 16, 2023 Share Posted February 16, 2023 10 hours ago, Quistess Alpha said: AFAIK, no. if sending large amounts of data in 1024 length packets (as you alluded to in another post) and you really need to keep the order Would there even be packets involved if the communication is purely object-to-object, since the process stays on the simulator the whole time? (I genuinely don't know.) 2 Link to comment Share on other sites More sharing options...
Quistess Alpha Posted February 16, 2023 Share Posted February 16, 2023 23 minutes ago, Wulfie Reanimator said: Would there even be packets involved if the communication is purely object-to-object, since the process stays on the simulator the whole time? (I genuinely don't know.) I was using packets in an anecdotal sense, no clue about server implementation either... 1 Link to comment Share on other sites More sharing options...
Love Zhaoying Posted February 16, 2023 Author Share Posted February 16, 2023 5 hours ago, Wulfie Reanimator said: Would there even be packets involved if the communication is purely object-to-object, since the process stays on the simulator the whole time? (I genuinely don't know.) If the definition of "a packet" is a "transaction" sending / receiving a single chunk of 1024 max bytes..yes. By the "network stack" definition..possibly not, if the sender and receiver are on the same host. But in "reality", I suspect assume the messaging system for llSay(), llRegionSayTo(), and listen() events uses some old "message queuing" software (whether homegrown or purchased like ancient MQ). That message queueing software will be dealing with incoming / outgoing "packets" at some point due to messages that do not originate on or go to the same simulator.. I think the 1024 byte max is way out of date. Link to comment Share on other sites More sharing options...
Qie Niangao Posted February 16, 2023 Share Posted February 16, 2023 Speaking of packets: Would it be crazy to only use llRegionSayTo() for establishing HTTP comms for the actual data transmission? That involves some overhead (need to mind the rate throttle, etc), but surely less than making and breaking links, or patching together message fragments (in order or not). Link to comment Share on other sites More sharing options...
Love Zhaoying Posted February 16, 2023 Author Share Posted February 16, 2023 (edited) No? But, I chose llRegionSayTo() for HUD/Client to Disk/Server because supposedly it's not throttled or delayed. If true, then it's not crazy to use it for anything where you want to avoid that throttle / delay. Edited February 16, 2023 by Love Zhaoying 1 Link to comment Share on other sites More sharing options...
primerib1 Posted February 18, 2023 Share Posted February 18, 2023 On 2/16/2023 at 1:10 AM, Love Zhaoying said: I was thinking about the other option, let the packets get there in random order with index information: "Here is a packet with LSD Key Blah, value Foo, this is Packet 3 of 5 packets for this Key". So, the Receiver would be able to hold all the packets and reassemble them once all 5 were received. This may be a little faster than the ACK/NAK solution, since the Sender would not wait for an ACK before sending the next packet. I personally think using the first character as ordering / end of sequence is a good idea. Use 0x20 .. 0x7E for ordering, last 'packet' always has 0x7F If you need several interspersed sequences, use the first byte as the sequence number (0x20..0x7E), the second byte as the packet number (0x20..0x7F) Then the receiver can grab all packets even out of order, put in a list until it sees a packet starting only 0x7F (end of transmission), then do a simple llListSort() and all packets are already in-order ready to be reconstituted. Sure this reduces max-usable packet size to 1023 (or 1022) characters, but you'll get easy reordering ability. Then you just iterate the list, and terminate a sequence everytime it sees 0x7F in the second byte. Link to comment Share on other sites More sharing options...
Recommended Posts
Please take a moment to consider if this thread is worth bumping.
Please sign in to comment
You will be able to leave a comment after signing in
Sign In Now