rtcChannelIdFor function
The data-channel id for streamName, derived identically on both peers.
negotiated: true requires both ends to pick the same integer without
exchanging anything, and the only thing both ends provably agree on before
the channel exists is the stream's name.
Collision properties, stated plainly. This is a hash into
[reservedIds, maxChannelId], so two differently-named streams can collide,
and the consequence would be two streams silently sharing a channel. That is
a corruption bug, not a performance one, so RtcMesh asserts on collision at
open time rather than trusting the hash — within one process a collision
fails loudly instead of crossing the wire. A session whose streams collide
must rename one; there are 65024 ids and sessions have a handful of streams,
so this is a guard, not a workflow.
Implementation
int rtcChannelIdFor(String streamName) {
if (streamName == coordinationChannelName) return coordinationChannelId;
// FNV-1a, 32-bit. Chosen for being short, stable across Dart versions and
// platforms, and dependency-free — `streamName.hashCode` is none of those.
var hash = 0x811c9dc5;
for (final unit in streamName.codeUnits) {
hash ^= unit & 0xff;
// The FNV prime is 2^24 + 0x193, multiplied in two parts. `hash * prime`
// in one step reaches ~2^56, past the 2^53 a JS number holds exactly, so
// on the web it rounded and web and native peers derived different ids
// for the same stream -- and never connected. `hash * 2^24 mod 2^32` is
// just the low byte shifted up, and `hash * 0x193` stays under 2^41.
hash = (hash * 0x193 + ((hash & 0xff) << 24)) & 0xffffffff;
}
final span = maxChannelId - reservedChannelIds + 1;
return reservedChannelIds + (hash % span);
}