Friday, September 20, 2024 7:40:52 AM
> settings

Customize


Authenticate

> connection_server_rewrite.html.erb
<div class="title">
  Exile Server Manager Devlog: Connection Server Rewrite
</div>

<div class="summary">
  The connection workflow between the bot and the Arma 3 servers has been <a target="_blank" href="https://github.com/itsthedevman/esm_bot/pull/19">released</a>. It took three months of my free time to complete, which isn’t bad for me given that the version I had from a year ago took about double that. Whereas it was a good first step, but I wasn't satisfied with it. Here’s what bothered me...
</div>

<div class="content">
  <h3>I Have Done It... I Have Finally Done It</h3>

  <p>
    The connection workflow between the bot and the Arma 3 servers has been <a target="_blank" href="https://github.com/itsthedevman/esm_bot/pull/19">released</a>. It took three months of my free time to complete, which isn’t bad for me given that the version I had from a year ago took about double that. Whereas it was a good first step, but I wasn't satisfied with it. Here’s what bothered me:
  </p>

  <ul>
    <li>It required running a separate Rust process to act as a middleman between the bot and the TCP connection from the Arma 3 (A3) server.</li>
    <li>The message protocol was too strict in the wrong ways, relied on callbacks, and was difficult to test.</li>
    <li>The communication between the Ruby process (running the bot) and the Rust process (running the TCP server) was overly complex and caused weird bugs.</li>
  </ul>

  <p>
    Using what I learned from writing <a target="_blank" href="https://github.com/itsthedevman/redis_ipc">redis_ipc</a>, I created a Ruby-based <a target="_blank" href="https://github.com/itsthedevman/esm_bot/blob/main/lib/esm/connection/server.rb">TCP server</a> to replace the <a target="_blank" href="https://github.com/itsthedevman/esm_bot/tree/73ae920e252ec7a892a083623cb76d5a765dd0b4/extension_server/src">Rust one</a>, simplifying a significant portion of the communication lifecycle. Instead of using an asynchronous callback-based system, I moved to a system that appears synchronous from the <a href="https://github.com/itsthedevman/esm_bot/blob/main/lib/esm/command/base/helpers.rb#L349-L356" target="_blank">implementation perspective</a> but functions asynchronously <a href="https://github.com/itsthedevman/esm_bot/blob/main/lib/esm/connection/client.rb#L88-L93" target="_blank">internally</a>. The usefulness of this simple change became clear when I ported the <a target="_blank" href="https://esmbot.com/wiki/commands#server_territories">server_territories</a> command and realized that I no longer needed to use the <code>#on_response</code> callback. Check out the <a href="https://github.com/itsthedevman/esm_bot/blob/main/lib/esm/command/territory/server_territories.rb#L50-L68" target="_blank">V1</a> vs <a href="https://github.com/itsthedevman/esm_bot/blob/main/lib/esm/command/territory/server_territories.rb#L39-L47" target="_blank">V2</a> implementations.
  </p>

  <p>
    While implementing the new workflows, I also switched to using <code>Hash/HashMap</code> to store key/value pairs in the data and metadata fields of <a target="_blank" href="https://github.com/itsthedevman/esm_bot/blob/main/lib/esm/message.rb#L68-L89"><code>ESM::Message</code></a> and its <a target="_blank" href="https://github.com/itsthedevman/esm_arma/blob/main/src/esm/src/message.rs">Rust counterpart</a>. This change removes some guarantees provided by Rust's structs, but the flexibility it offers saves me from using my previously implemented <a rel="noreferrer" target="_new" href="https://github.com/itsthedevman/esm_arma/blob/5265d098ae50648e2b84679d807904000de19fc1/src/message/message_proc/src/lib.rs">attribute macro</a>, which was intended to reduce the amount of Rust boilerplate code required to function with <a rel="noreferrer" target="_new" href="https://github.com/BrettMayson/arma-rs">arma-rs</a> and <a rel="noreferrer" target="_new" href="https://github.com/serde-rs/serde">serde</a>.
  </p>

  <p>
    The last major change I made was to reworked the encryption process to occur as <a href="https://github.com/itsthedevman/esm_bot/blob/main/lib/esm/connection/client/lifecycle.rb#L67-L94" target="_blank">early as possible</a>, ensuring no unencrypted data is sent to the client. Additionally, I added <a rel="noreferrer" target="_new" href="https://en.wikipedia.org/wiki/Gzip">gzip compression</a> and <a rel="noreferrer" target="_new" href="https://en.wikipedia.org/wiki/Base64">base64 encoding</a> to keep the data small and prevent data loss. I will create a separate post detailing the networking lifecycle at a later point.
  </p>

  <h3>What’s Next?</h3>
  <p>
    My next focus will be on migrating the remaining SQF command functions to the new mod and improving them as needed. I’m also working on enhancing the reliability and usability of XM8 notifications and have some treats in store for the reward command. More on those when I get there :)
  </p>
</div>
All opinions represented herein are my own
- © 2024 itsthedevman
- build 340fbb8