Skip to content

Commit 49fad85

Browse files
committed
Tidy up webrtc nostr example.
1 parent 22e4d03 commit 49fad85

2 files changed

Lines changed: 17 additions & 56 deletions

File tree

examples/WebRTCExamples/WebRTCNostrSignalling/Program.cs

Lines changed: 16 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ class Program
7777
private static Microsoft.Extensions.Logging.ILogger logger = NullLogger.Instance;
7878
private static NostrClient? nostrClient;
7979
private static RTCPeerConnection? peerConnection;
80-
private static string? localPeerId;
8180
private static string? remotePeerId;
8281

8382
// Nostr identity for this process.
@@ -91,7 +90,17 @@ class Program
9190
private static ECXOnlyPubKey remotePubKey =
9291
ECXOnlyPubKey.Create(Convert.FromHexString(remotePubKeyHex));
9392
private static bool isOfferer = false;
94-
private static bool signallingStarted = false; // Track if offer/answer exchange has started
93+
private static bool signallingStarted = false; // Track if offer/answer exchange has started
94+
95+
// Pending remote ICE candidates received before the remote description
96+
// has been applied. They get drained once setRemoteDescription
97+
// succeeds. Without buffering, an IceCandidate that arrives at the
98+
// offerer before the Answer (Nostr does not preserve ordering across
99+
// events) would be applied to a peer connection with no remote
100+
// description and the ICE checks against the answerer would never
101+
// start.
102+
private static readonly List<RTCIceCandidateInit> pendingRemoteCandidates = new();
103+
private static bool remoteDescriptionApplied = false;
95104

96105
static async Task Main(string[] args)
97106
{
@@ -112,10 +121,7 @@ static async Task Main(string[] args)
112121
//localPrivateKey = ECPrivKey.Create(localPrivKeyBytes);
113122
//localPubKeyHex = localPrivateKey.CreateXOnlyPubKey().ToHex();
114123

115-
localPeerId = localPubKeyHex[..8];
116-
Console.WriteLine($"Your Peer ID (short): {localPeerId}");
117124
Console.WriteLine($"Your Peer ID (full): {localPubKeyHex}");
118-
Console.WriteLine($"Private key: {localPrivateKey.ToHex()}");
119125

120126
// Connect to Nostr relay
121127
Console.WriteLine($"Connecting to Nostr relay at {NOSTR_RELAY_URL}...");
@@ -205,7 +211,7 @@ private static async Task ConnectToNostrRelay()
205211
var filter = new NostrSubscriptionFilter
206212
{
207213
Kinds = new[] { WEBRTC_SIGNAL_KIND },
208-
ReferencedPublicKeys = new[] { localPubKeyHex! }
214+
ReferencedPublicKeys = new[] { localPubKeyHex }
209215
};
210216

211217
// Create subscription
@@ -222,16 +228,6 @@ private static async Task ConnectToNostrRelay()
222228
}
223229
}
224230

225-
// Pending remote ICE candidates received before the remote description
226-
// has been applied. They get drained once setRemoteDescription
227-
// succeeds. Without buffering, an IceCandidate that arrives at the
228-
// offerer before the Answer (Nostr does not preserve ordering across
229-
// events) would be applied to a peer connection with no remote
230-
// description and the ICE checks against the answerer would never
231-
// start.
232-
private static readonly System.Collections.Generic.List<RTCIceCandidateInit> pendingRemoteCandidates = new();
233-
private static bool remoteDescriptionApplied = false;
234-
235231
private static void DrainPendingRemoteCandidates()
236232
{
237233
if (peerConnection == null) { return; }
@@ -257,15 +253,14 @@ private static void OnNostrEventsReceived(object? sender, (string subscriptionId
257253
{
258254
try
259255
{
260-
logger.LogDebug($"Processing Nostr event: id={nostrEvent.Id?[..8]}..., kind={nostrEvent.Kind}");
256+
logger.LogDebug($"Processing Nostr event: id={nostrEvent.Id}..., kind={nostrEvent.Kind}");
261257

262258
if (string.IsNullOrEmpty(nostrEvent.Content))
263259
{
264260
logger.LogDebug("Nostr event has empty content, skipping");
265261
continue;
266262
}
267263

268-
269264
// event.Content is the NIP-44 v2 base64 ciphertext.
270265
// Inverse of the publish path: NIP-44 decrypt -> json.
271266
string jsonContent;
@@ -276,7 +271,7 @@ private static void OnNostrEventsReceived(object? sender, (string subscriptionId
276271
catch (Exception decryptEx)
277272
{
278273
logger.LogWarning(decryptEx,
279-
$"NIP-44 decrypt failed (event may be from a different peer or use a different key); skipping event {nostrEvent.Id?[..8]}...");
274+
$"NIP-44 decrypt failed (event may be from a different peer or use a different key); skipping event {nostrEvent.Id}...");
280275
continue;
281276
}
282277

@@ -290,15 +285,6 @@ private static void OnNostrEventsReceived(object? sender, (string subscriptionId
290285

291286
logger.LogDebug($"Parsed signal message: type={message.Type}, from={message.PeerId}, to={message.TargetPeerId}");
292287

293-
// Check if this message is for us
294-
if (message.TargetPeerId != localPeerId)
295-
{
296-
logger.LogDebug($"Message not for us (target={message.TargetPeerId}, local={localPeerId}), skipping");
297-
continue;
298-
}
299-
300-
logger.LogInformation($"Received {message.Type} from peer {message.PeerId}");
301-
302288
// Process the message asynchronously with error handling
303289
_ = Task.Run(async () =>
304290
{
@@ -319,7 +305,7 @@ private static void OnNostrEventsReceived(object? sender, (string subscriptionId
319305
}
320306
catch (Exception ex)
321307
{
322-
logger.LogWarning($"Failed to process Nostr event: {ex.Message}");
308+
logger.LogWarning($"Failed to process Nostr event {nostrEvent.Id}: {ex.Message}");
323309
}
324310
}
325311
}
@@ -361,7 +347,6 @@ private static async Task ProcessSignalMessage(NostrSignalMessage message)
361347
await SendSignalMessage(new NostrSignalMessage
362348
{
363349
Type = NostrSignalType.Answer,
364-
PeerId = localPeerId,
365350
TargetPeerId = remotePeerId,
366351
Sdp = answerSdp.sdp
367352
});
@@ -467,7 +452,7 @@ private static async Task SendSignalMessage(NostrSignalMessage message)
467452
new NostrEventTag
468453
{
469454
TagIdentifier = "p",
470-
Data = new List<string> { remotePubKeyHex! }
455+
Data = new List<string> { remotePubKeyHex }
471456
}
472457
}
473458
};
@@ -534,17 +519,6 @@ private static RTCPeerConnection CreatePeerConnection()
534519
var testPatternSource = new VideoTestPatternSource(vp8Codec);
535520
var audioSource = new AudioExtrasSource(new AudioEncoder(), new AudioSourceOptions { AudioSource = AudioSourcesEnum.Music });
536521

537-
// Tracks are SendOnly because the C# side only ever sources
538-
// media (a video test pattern + a music audio source) and has no
539-
// sink to render received media into. SendRecv would generate an
540-
// answer SDP whose direction is incompatible with a browser
541-
// offer that sets the transceivers as recvonly:
542-
//
543-
// InvalidAccessError: Failed to set remote answer sdp:
544-
// Incompatible send direction
545-
//
546-
// SendOnly answers the browser cleanly and also produces a
547-
// self-consistent offer when the C# side initiates the call.
548522
MediaStreamTrack videoTrack = new MediaStreamTrack(testPatternSource.GetVideoSourceFormats(), MediaStreamStatusEnum.SendOnly);
549523
pc.addTrack(videoTrack);
550524
MediaStreamTrack audioTrack = new MediaStreamTrack(audioSource.GetAudioSourceFormats(), MediaStreamStatusEnum.SendOnly);
@@ -572,7 +546,6 @@ private static RTCPeerConnection CreatePeerConnection()
572546
await SendSignalMessage(new NostrSignalMessage
573547
{
574548
Type = NostrSignalType.IceCandidate,
575-
PeerId = localPeerId,
576549
TargetPeerId = remotePeerId,
577550
Candidate = iceCandidate.candidate,
578551
SdpMid = iceCandidate.sdpMid,
@@ -611,18 +584,6 @@ await SendSignalMessage(new NostrSignalMessage
611584
}
612585
else if (state == RTCPeerConnectionState.closed)
613586
{
614-
// Detach the encoded-sample event handlers BEFORE awaiting
615-
// CloseVideo/CloseAudio. The audio source in particular
616-
// produces a packet every ~20 ms and there are typically
617-
// a handful already in flight when the peer connection
618-
// transitions to closed. Without this detach each one
619-
// racing past the close boundary fires
620-
// pc.SendAudio -> RTPSession.SendRtpRaw
621-
// -> [WRN] SendRtpRaw was called for a audio packet
622-
// on a closed RTP session.
623-
// Video happens to be quieter (a frame every 33 ms at
624-
// 30 fps) so the symptom is mostly visible on audio,
625-
// but unsubscribe both for symmetry.
626587
testPatternSource.OnVideoSourceEncodedSample -= pc.SendVideo;
627588
audioSource.OnAudioSourceEncodedSample -= pc.SendAudio;
628589

examples/WebRTCExamples/WebRTCNostrSignalling/WebRTCNostrSignalling.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>

0 commit comments

Comments
 (0)