Learnings from 100ms Dive

These are my learnings while looking into the 100ms repos, inspecting devtools and trying to bind all these into something that make sense.

I might be horribly wrong at understanding these but either way I get to learn something. So here we go.

Repos

My starting point was from the web-app, opened up devtools -> network tab.

Preview

Initial log

# Socket Connection Journey

[HMSTransport]: connect: started ⏰

InitService fetchInitConfig: initEndpoint=https://prod-init.100ms.live/init

[HMSTransport]: ⏳ internal connect: connecting to ws endpoint

[HMSTransport]: ✅ internal connect: connected to ws endpoint

Opening a Websocket connection: Code

Preview establishes a Websocket connection and keeps sending ping pong messages.

Upon opening WS panel

initially you can see on-role-change & on-policy-change

Looks like info around roles but why do both exist? what is the difference?

on-role-change message
{
  "method": "on-role-change",
  "params": {
    "role": {
      "name": "host",
      "publishParams": {
        "allowed": ["audio", "video", "screen"],
        "audio": { "bitRate": 32, "codec": "opus" },
        "video": {
          "bitRate": 1000,
          "codec": "vp8",
          "frameRate": 30,
          "width": 960,
          "height": 720
        },
        "screen": {
          "codec": "vp8",
          "frameRate": 10,
          "width": 1920,
          "height": 1080
        },
        "videoSimulcastLayers": {},
        "screenSimulcastLayers": {}
      },
      "subscribeParams": {
        "subscribeToRoles": ["host", "guest"],
        "maxSubsBitRate": 8000,
        "subscribeDegradation": {}
      },
      "permissions": {
        "endRoom": true,
        "removeOthers": true,
        "mute": true,
        "unmute": true,
        "changeRole": true
      },
      "priority": 1
    }
  },
  "jsonrpc": "2.0"
}
on-policy-change message
{
  "method": "on-policy-change",
  "params": {
    "name": "host",
    "known_roles": {
      "guest": {
        "name": "guest",
        "publishParams": {
          "allowed": ["audio", "video"],
          "audio": { "bitRate": 32, "codec": "opus" },
          "video": {
            "bitRate": 400,
            "codec": "vp8",
            "frameRate": 30,
            "width": 640,
            "height": 480
          },
          "screen": {
            "codec": "vp8",
            "frameRate": 10,
            "width": 1920,
            "height": 1080
          },
          "videoSimulcastLayers": {},
          "screenSimulcastLayers": {}
        },
        "subscribeParams": {
          "subscribeToRoles": ["host", "guest"],
          "maxSubsBitRate": 5200,
          "subscribeDegradation": {}
        },
        "permissions": {},
        "priority": 1
      },
      "host": {
        "name": "host",
        "publishParams": {
          "allowed": ["audio", "video", "screen"],
          "audio": { "bitRate": 32, "codec": "opus" },
          "video": {
            "bitRate": 1000,
            "codec": "vp8",
            "frameRate": 30,
            "width": 960,
            "height": 720
          },
          "screen": {
            "codec": "vp8",
            "frameRate": 10,
            "width": 1920,
            "height": 1080
          },
          "videoSimulcastLayers": {},
          "screenSimulcastLayers": {}
        },
        "subscribeParams": {
          "subscribeToRoles": ["host", "guest"],
          "maxSubsBitRate": 8000,
          "subscribeDegradation": {}
        },
        "permissions": {
          "endRoom": true,
          "removeOthers": true,
          "mute": true,
          "unmute": true,
          "changeRole": true
        },
        "priority": 1
      }
    }
  },
  "jsonrpc": "2.0"
}

Every 1 second this happens:

Observation: method ping is an action (call) and the response is the timestamp this is how jsonrpc 2.0 is standardized. jsonprc is also one of the interface provided by Pion SFU.

The call function that sends JSONRPC request -> Code

This is where ping is called Code

On the "Backend" pingHandler function handles the results sent to the client.

This is where all methods enums reside.

I disconnect my internet then connect in preview and then join, i don't see any messages/pings in WS why? logs do say my Window and Transport has connected. (nvm new connection is established)

Join

upon clicking join we now send a new method: join with SDP offer as params.

join message
{
  "method": "join",
  "params": {
    "name": "Deep",
    "disableVidAutoSub": true,
    "data": "",
    "offer": {
      "type": "offer",
      "sdp": "v=0\r\no=- 997832987756044998 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\nm=application 9 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:QNrR\r\na=ice-pwd:YLb9lH802wEeI8Y4PbCLFr2O\r\na=ice-options:trickle\r\na=fingerprint:sha-256 75:CE:1E:6B:72:1E:CB:21:6B:1C:EB:AE:03:FF:C9:79:36:9F:24:61:5B:2C:7A:D7:B7:CE:47:7F:90:6F:00:C7\r\na=setup:actpass\r\na=mid:0\r\na=sctp-port:5000\r\na=max-message-size:262144\r\n"
    }
  },
  "id": "142530e9-ff3f-4db1-8fa9-0217915309ba",
  "jsonrpc": "2.0"
}

Then the join method sends these params (SDP) to "biz" via the call method.

Now I am seeing some messages of method trickle looks like ICE candidate.

trickle message
{
  "method": "trickle",
  "params": {
    "target": 0,
    "candidate": {
      "candidate": "candidate:3350409123 1 udp 2113937151 ebbcc4b9-7270-4ec2-abac-a7e9766ada98.local 61016 typ host generation 0 ufrag QNrR network-cost 999",
      "sdpMid": "0",
      "sdpMLineIndex": 0
    }
  }
}

Then an offer comes from "biz" , peer-list method with peers, trickle, trickle, trickle, "answer" method (need to learn more).

Now that I know the enum method JOIN = 'join' finding this in biz should be easy. On the "biz" side it's called PeerJoin.

Add peer in local room Code

Joining in the SFU client: Code

Then Delete from local room Code

Why local room?