Download Game! Currently 74 players and visitors. Last logged in:WicksiusDraxxSebaotLouisiana

Blitzer's Blog >> 71702

Back to blogs index
Posted: 07 Aug 2026 14:56 [ permalink ]
TC$mC$ on erinomainen suunta! Se, ettC$ tuetaan molempia (TCP ja UDP)
dynaamisesti ja automaattisesti, on juuri se tapa, jolla ammattimaiset
P2P-verkot (kuten WebRTC tai BitTorrentin lokaalit protokollat) toimivat
"pellin alla".

TC$ssC$ mallissa vC$ltetC$C$n monimutkaiset ulkoiset riippuvuudet
hyC6dyntC$mC$llC$ kummankin protokollan vahvuuksia:

* **UDP:** Toimii verkon "sydC$menlyC6ntinC$" (GOSSIP/Autodiscovery) ja
**fallback-reittinC$**, koska se on tilaton (connectionless) eikC$ vC$litC$
siitC$, onko yhteys auki vai ei.
* **TCP:** Toimii **pC$C$vC$ylC$nC$** raskaammalle datalle (CHUNKS, isot
JSON-objektit), koska se takaa pakettien jC$rjestyksen ja eheyden.

### Miten automaattinen vaihto ja kC$ttely (Handshake) toimii?

1. **KC$ynnistys:** Instanssi etsii vapaan portin (esim. `33000`) ja avaa
siihen *sekC$* UDP-kuuntelijan ettC$ TCP-palvelimen.
2. **Discovery (UDP):** Instanssi alkaa huutaa UDP-broadcastilla
GOSSIP-viestejC$ verkkoon (esim. 2 sekunnin vC$lein). ViestissC$ lukee
instanssin ID ja sen TCP-portti.
3. **KC$ttely (Handshake):** Kun Node A kuulee Node B:n UDP-viestin:
* Jos Node A:lla ei ole vielC$ TCP-yhteyttC$ Node B:hen, se yrittC$C$ avata
sen.
* Jos TCP-yhteys onnistuu, tila muuttuu: `connected: TCP`.


4. **Reititys ja Fallback:**
* Kun sovellus lC$hettC$C$ viestin, reititin katsoo peer-taulua.
* Jos TCP on auki, viesti menee sinne.
* Jos TCP menee poikki (yhteysvirhe/timeout), TCP-soketti tuhotaan. Seuraava
viesti menee automaattisesti **UDP:llC$**.


5. **Auto-Reconnect:** Koska UDP-GOSSIP laulaa taustalla jatkuvasti, seuraavan
kerran kun Node B:ltC$ tulee UDP-sydC$menlyC6nti, Node A huomaa, ettC$ TCP
puuttuu, ja **yrittC$C$ automaattista uudelleenkC$ttelyC$**.

### Konkreettinen Node.js Vanilla -toteutus

### Miten sovellus kC$yttC$C$ tC$tC$?

Koska verkkokerros piilottaa TCP/UDP-kompleksisuuden ja auto-fallbackin,
sovelluksen logiikka on pelkkC$C$ "lue laatikkoa" ja "lC$hetC$ viestiC$":

```javascript
import { HybridMeshNode } from './mesh.js';

async function main() {
    const node = new HybridMeshNode("MyBot_1");
    await node.start(); // Etsii portin 33000-33999, kC$ynnistC$C$ palvelimet
ja gossipin

    // 1. KC$ynnistC$ Mailboxin kuuntelija-looppi
    (async () => {
        for await (const msg of node.inbox) {
            // msg.type: 0 = GOSSIP, 1 = OPS, 2 = CHAT, jne.
            if (msg.type === 0) {
                // Gossip on vain lokitettavaksi tai verkon visualisointiin
                // console.log(`[${msg.protocol}] NC$hty peer:`,
msg.senderId);
            } 
            else if (msg.type === 2) {
                console.log(`[CHAT saapui via ${msg.protocol}]:
${msg.payload.text}`);
            }
        }
    })();

    // 2. Simuloidaan viestin lC$hetystC$ toiselle instanssille
    // Todellisuudessa lukisit kohdeID:n peer-taulusta tai broadcastaisit
(targetId: null)
    setInterval(() => {
        const peers = Array.from(node.peers.keys());
        if (peers.length > 0) {
            // LC$hetetC$C$n satunnaiselle tunnetulle peerille viesti
            node.send(peers[0], 2, ["chat"], { text: "Hei tC$C$ltC$ Node
ykkC6sestC$!" });
        }
    }, 5000);
}

main();

```

### TC$rkeC$t huomiot (Caveats)

1. **UDP:n kokorajoitus:** UDP-protokollan luonteen takia MTU (Maximum
Transmission Unit) asettaa rajan. Jos kC$ytC$t reitittimen fallbackina
UDP:tC$, viestin koon (`JSON.stringify` tulos) on syytC$ pysyC$ alle **1400
tavussa**. Jos yritC$t lC$hettC$C$ 5 megan kuvan UDP:llC$ tuolla koodilla, se
katoaa bittiavaruuteen. TCP hoitaa isotkin tiedostot automaattisesti, koska se
pilkkoo ja kokoaa ne puskureissa.
2. **TCP:n Framing:** TCP lukee dataa "putkena". Vaikka lC$hettC$isit kaksi
erillistC$ JSON-viestiC$ nopeasti, ne voivat saapua kohteeseen yhtenC$
merkkijonona. Siksi koodissani on `rawMsg.toString().trim().split('
')`. LC$hetyspuolella lisC$tC$C$n aina rivinvaihto (`
`), ja lukupuolella data pilkotaan rivinvaihdoista takaisin erillisiksi
JSON-objekteiksi. TC$mC$ on kevyin mahdollinen tapa erottaa viestit
toisistaan.

MitC$ pidC$t tC$stC$ dynamiikasta? TC$mC$ tarjoaa erittC$in robustin pohjan,
joka parantuu katkoista itsekseen ilman ulkoisia message-brokereita (kuten
RabbitMQ tai Redis).