It's still broken, but I made a bit of progress.
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
using RelayClient.Crypto;
|
using RelayClient.Crypto;
|
||||||
using RelayClient.Models;
|
using RelayClient.Models;
|
||||||
using WebSocketSharp;
|
using WebSocketSharp;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
@@ -109,7 +109,7 @@ public partial class MainPage : ContentPage
|
|||||||
|
|
||||||
SafeSendRawToWebView($"[{_username}] RAW WS DATA: {e.Data}");
|
SafeSendRawToWebView($"[{_username}] RAW WS DATA: {e.Data}");
|
||||||
|
|
||||||
Console.WriteLine($"[{_username}] RAW WS DATA: {e.Data}");
|
//Console.WriteLine($"[{_username}] RAW WS DATA: {e.Data}");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -198,8 +198,8 @@ public partial class MainPage : ContentPage
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == "rtc_offer_updated" || type == "rtc_answer_updated" || type == "rtc_candidate_added" || type == "rtc_call_left")
|
if (type is "rtc_offer_updated" or "rtc_answer_updated" or "rtc_candidate_added" or "rtc_call_left")
|
||||||
{
|
{
|
||||||
var rtcNotification = JsonSerializer.Deserialize<RtcNotificationMessage>(e.Data);
|
var rtcNotification = JsonSerializer.Deserialize<RtcNotificationMessage>(e.Data);
|
||||||
if (rtcNotification is null)
|
if (rtcNotification is null)
|
||||||
@@ -213,40 +213,10 @@ public partial class MainPage : ContentPage
|
|||||||
|
|
||||||
SafeSendRawToWebView("RTC notification received: " + notificationType + " for " + notificationChannelId);
|
SafeSendRawToWebView("RTC notification received: " + notificationType + " for " + notificationChannelId);
|
||||||
|
|
||||||
MainThread.BeginInvokeOnMainThread(async () =>
|
_ = MainThread.InvokeOnMainThreadAsync(() => HandleRtcNotificationAsync(notificationType));
|
||||||
{
|
|
||||||
switch (notificationType)
|
|
||||||
{
|
|
||||||
case "rtc_offer_updated":
|
|
||||||
{
|
|
||||||
var offer = await GetRtcOffer();
|
|
||||||
await SendRtcSignalToJsAsync(offer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "rtc_answer_updated":
|
|
||||||
{
|
|
||||||
var answer = await ServerAPI.GetAnswerForChannelAsync(_currentChannelId);
|
|
||||||
if (answer is not null)
|
|
||||||
{
|
|
||||||
await AnswerCallback(answer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "rtc_candidate_added":
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "rtc_call_left":
|
|
||||||
{
|
|
||||||
SafeSendRawToWebView("RTC call left notification received.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type != "encrypted_chat")
|
if (type != "encrypted_chat")
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -477,23 +447,22 @@ public partial class MainPage : ContentPage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task AnswerCallback(RtcDescription answer)
|
//public async Task AnswerCallback(RtcDescription answer)
|
||||||
{
|
//{
|
||||||
string json = JsonSerializer.Serialize(answer);
|
// string json = JsonSerializer.Serialize(answer);
|
||||||
SafeSendRawToWebView("WriteRtcAnswer answered with: " + json);
|
// SafeSendRawToWebView("WriteRtcAnswer answered with: " + json);
|
||||||
try
|
|
||||||
{
|
// try
|
||||||
SafeSendRawToWebView("Pre");
|
// {
|
||||||
// await hybridWebView.InvokeJavaScriptAsync("CSharpCallTest", ["value from C#"], [HybridJSTypeString.Default.String]);
|
// SafeSendRawToWebView("Pre Evaluate");
|
||||||
// SafeSendRawToWebView("Mid");
|
// await hybridWebView.EvaluateJavaScriptAsync($"window.AnswerCallback({json})");
|
||||||
await hybridWebView.InvokeJavaScriptAsync("AnswerCallback", [json], [HybridJSTypeString.Default.String]);
|
// SafeSendRawToWebView("Post Evaluate");
|
||||||
SafeSendRawToWebView("End");
|
// }
|
||||||
}
|
// catch (Exception ex)
|
||||||
catch (Exception ex)
|
// {
|
||||||
{
|
// SafeSendRawToWebView("WriteRtcAnswer failed: " + ex.Message);
|
||||||
SafeSendRawToWebView("WriteRtcAnswer failed: " + ex.Message);
|
// }
|
||||||
}
|
//}
|
||||||
}
|
|
||||||
|
|
||||||
private void OnSendMessageButtonClicked(object sender, EventArgs e)
|
private void OnSendMessageButtonClicked(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
@@ -508,7 +477,8 @@ public partial class MainPage : ContentPage
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await DisplayAlertAsync("Raw Message Received", e.Message, "OK");
|
Console.WriteLine($"[{_username}] JS RAW -> C#: {e.Message}");
|
||||||
|
SafeSendRawToWebView($"JS RAW -> C#: {e.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendRtcSignal(string json)
|
public void SendRtcSignal(string json)
|
||||||
@@ -552,8 +522,12 @@ public partial class MainPage : ContentPage
|
|||||||
|
|
||||||
private async Task SendRtcSignalToJsAsync(string rawJson)
|
private async Task SendRtcSignalToJsAsync(string rawJson)
|
||||||
{
|
{
|
||||||
|
SafeSendRawToWebView("Before Evaluate dispatchRtcSignal");
|
||||||
|
|
||||||
var jsArg = JsonSerializer.Serialize(rawJson);
|
var jsArg = JsonSerializer.Serialize(rawJson);
|
||||||
await hybridWebView.EvaluateJavaScriptAsync($"window.handleRtcSignal({jsArg})");
|
await hybridWebView.EvaluateJavaScriptAsync($"window.dispatchRtcSignal({jsArg})");
|
||||||
|
|
||||||
|
SafeSendRawToWebView("After Evaluate dispatchRtcSignal");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task PushRtcContextToJsAsync()
|
private async Task PushRtcContextToJsAsync()
|
||||||
@@ -597,4 +571,65 @@ public partial class MainPage : ContentPage
|
|||||||
// for trimmed builds.
|
// for trimmed builds.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task HandleRtcNotificationAsync(string notificationType)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
switch (notificationType)
|
||||||
|
{
|
||||||
|
case "rtc_offer_updated":
|
||||||
|
{
|
||||||
|
var offer = await ServerAPI.GetOffersForChannelAsync(_currentChannelId);
|
||||||
|
if (offer is not null)
|
||||||
|
{
|
||||||
|
var signal = new
|
||||||
|
{
|
||||||
|
type = "rtc_offer",
|
||||||
|
from = "server",
|
||||||
|
channelId = _currentChannelId,
|
||||||
|
sdp = offer.sdp
|
||||||
|
};
|
||||||
|
|
||||||
|
SafeSendRawToWebView("Dispatching rtc_offer to JS");
|
||||||
|
await SendRtcSignalToJsAsync(JsonSerializer.Serialize(signal));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "rtc_answer_updated":
|
||||||
|
{
|
||||||
|
var answer = await ServerAPI.GetAnswerForChannelAsync(_currentChannelId);
|
||||||
|
if (answer is not null)
|
||||||
|
{
|
||||||
|
var signal = new
|
||||||
|
{
|
||||||
|
type = "rtc_answer",
|
||||||
|
from = "server",
|
||||||
|
channelId = _currentChannelId,
|
||||||
|
sdp = answer.sdp
|
||||||
|
};
|
||||||
|
|
||||||
|
SafeSendRawToWebView("Dispatching rtc_answer to JS");
|
||||||
|
await SendRtcSignalToJsAsync(JsonSerializer.Serialize(signal));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "rtc_candidate_added":
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "rtc_call_left":
|
||||||
|
{
|
||||||
|
SafeSendRawToWebView("RTC call left notification received.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
SafeSendRawToWebView("RTC notification handler failed: " + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
let peerConnection = null;
|
let peerConnection = null;
|
||||||
let localStream = null;
|
let localStream = null;
|
||||||
let currentUsername = null;
|
let currentUsername = null;
|
||||||
let currentChannelId = null;
|
let currentChannelId = null;
|
||||||
@@ -26,6 +26,30 @@ window.setChannelId = function(channelId) {
|
|||||||
LogMessage("Channel set to: " + currentChannelId);
|
LogMessage("Channel set to: " + currentChannelId);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//window.AnswerCallback = async function(answer) {
|
||||||
|
// try {
|
||||||
|
// LogMessage("AnswerCallback called with: " + JSON.stringify(answer));
|
||||||
|
//
|
||||||
|
// if (!peerConnection) {
|
||||||
|
// await ensurePeerConnection2();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (!answer || !answer.type || !answer.sdp) {
|
||||||
|
// LogMessage("AnswerCallback received invalid answer");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// await peerConnection.setRemoteDescription({
|
||||||
|
// type: answer.type,
|
||||||
|
// sdp: answer.sdp
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// LogMessage("Remote answer applied");
|
||||||
|
// } catch (err) {
|
||||||
|
// LogMessage("AnswerCallback failed: " + err);
|
||||||
|
// }
|
||||||
|
//};
|
||||||
|
|
||||||
function LogMessage(msg) {
|
function LogMessage(msg) {
|
||||||
const messageLog = document.getElementById("messageLog");
|
const messageLog = document.getElementById("messageLog");
|
||||||
messageLog.value += '\r\n' + msg;
|
messageLog.value += '\r\n' + msg;
|
||||||
@@ -218,16 +242,21 @@ async function ensurePeerConnection2()
|
|||||||
`ICE connection state change: ${peerConnection.iceConnectionState}`);
|
`ICE connection state change: ${peerConnection.iceConnectionState}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function channelCallJoin(activeCall)
|
async function channelCallJoin(activeCall)
|
||||||
{
|
{
|
||||||
LogMessage("Active call: " + activeCall);
|
LogMessage("Active call: " + activeCall);
|
||||||
|
|
||||||
await ensurePeerConnection2();
|
await ensurePeerConnection2();
|
||||||
|
await ensureLocalMedia();
|
||||||
|
|
||||||
if (activeCall)
|
if (activeCall)
|
||||||
{
|
{
|
||||||
const rawJson = await window.HybridWebView.InvokeDotNet("GetRtcOffer");
|
const rawJson = await window.HybridWebView.InvokeDotNet("GetRtcOffer");
|
||||||
const offer = typeof rawJson === "string" ? JSON.parse(rawJson) : rawJson;
|
const offer = typeof rawJson === "string" ? JSON.parse(rawJson) : rawJson;
|
||||||
|
|
||||||
await peerConnection.setRemoteDescription(offer);
|
await peerConnection.setRemoteDescription(offer);
|
||||||
|
|
||||||
const answer = await peerConnection.createAnswer();
|
const answer = await peerConnection.createAnswer();
|
||||||
await peerConnection.setLocalDescription(answer);
|
await peerConnection.setLocalDescription(answer);
|
||||||
|
|
||||||
@@ -241,21 +270,9 @@ async function channelCallJoin(activeCall)
|
|||||||
{
|
{
|
||||||
const offer = await peerConnection.createOffer();
|
const offer = await peerConnection.createOffer();
|
||||||
await peerConnection.setLocalDescription(offer);
|
await peerConnection.setLocalDescription(offer);
|
||||||
|
|
||||||
await window.HybridWebView.InvokeDotNet("WriteRtcOffer", [JSON.stringify(offer)]);
|
await window.HybridWebView.InvokeDotNet("WriteRtcOffer", [JSON.stringify(offer)]);
|
||||||
LogMessage(`Joining call with media offer: ${JSON.stringify(offer)}`);
|
LogMessage("Joining call with media offer: " + JSON.stringify(offer));
|
||||||
|
|
||||||
localStream.getTracks().forEach(track => {
|
|
||||||
peerConnection.addTrack(track, localStream);
|
|
||||||
});
|
|
||||||
|
|
||||||
peerConnection.addEventListener('track', event => {
|
|
||||||
LogMessage("Received track: " + event.streams[0]);
|
|
||||||
event.streams[0].getTracks().forEach(track => {
|
|
||||||
LogMessage(`Add a track to the remoteStream: ${track}`);
|
|
||||||
remoteStream.addTrack(track);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,20 +280,20 @@ async function CSharpCallTest(value)
|
|||||||
{
|
{
|
||||||
LogMessage("Called from C#: " + value);
|
LogMessage("Called from C#: " + value);
|
||||||
}
|
}
|
||||||
async function AnswerCallback(answer)
|
//async function AnswerCallback(answer)
|
||||||
{
|
//{
|
||||||
LogMessage("Answer: " + answer);
|
// LogMessage("Answer: " + answer);
|
||||||
|
//
|
||||||
let callBack = JSON.parse(answer);
|
// let callBack = JSON.parse(answer);
|
||||||
LogMessage("Call Back: " + callBack);
|
// LogMessage("Call Back: " + callBack);
|
||||||
|
//
|
||||||
if (!peerConnection.currentRemoteDescription && callBack)
|
// if (!peerConnection.currentRemoteDescription && callBack)
|
||||||
{
|
// {
|
||||||
LogMessage("Current answer: " + callBack);
|
// LogMessage("Current answer: " + callBack);
|
||||||
const desc = new RTCSessionDescription(answer);
|
// const desc = new RTCSessionDescription(answer);
|
||||||
await peerConnection.setRemoteDescription(desc);
|
// await peerConnection.setRemoteDescription(desc);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
async function CollectIceCandidates()
|
async function CollectIceCandidates()
|
||||||
{
|
{
|
||||||
@@ -284,6 +301,8 @@ async function CollectIceCandidates()
|
|||||||
}
|
}
|
||||||
async function handleRtcSignal(rawJson) {
|
async function handleRtcSignal(rawJson) {
|
||||||
try {
|
try {
|
||||||
|
LogMessage("handleRtcSignal raw: " + JSON.stringify(rawJson));
|
||||||
|
|
||||||
const msg = typeof rawJson === "string" ? JSON.parse(rawJson) : rawJson;
|
const msg = typeof rawJson === "string" ? JSON.parse(rawJson) : rawJson;
|
||||||
|
|
||||||
LogMessage("Received signal: " + msg.type + " from " + msg.from + " in " + msg.channelId);
|
LogMessage("Received signal: " + msg.type + " from " + msg.from + " in " + msg.channelId);
|
||||||
@@ -436,8 +455,15 @@ async function waitForIceGatheringComplete(pc) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function dispatchRtcSignal(rawJson) {
|
||||||
|
handleRtcSignal(rawJson);
|
||||||
|
return "ok";
|
||||||
|
}
|
||||||
|
|
||||||
window.handleRtcSignal = handleRtcSignal;
|
window.handleRtcSignal = handleRtcSignal;
|
||||||
|
|
||||||
|
window.dispatchRtcSignal = dispatchRtcSignal;
|
||||||
|
|
||||||
window.addEventListener("HybridWebViewMessageReceived", function (e) {
|
window.addEventListener("HybridWebViewMessageReceived", function (e) {
|
||||||
LogMessage("Raw message: " + e.detail.message);
|
LogMessage("Raw message: " + e.detail.message);
|
||||||
});
|
});
|
||||||
@@ -446,4 +472,9 @@ window.addEventListener("load", async () => {
|
|||||||
LogMessage("RTC page loaded");
|
LogMessage("RTC page loaded");
|
||||||
window.HybridWebView.SendRawMessage("rtc_page_ready");
|
window.HybridWebView.SendRawMessage("rtc_page_ready");
|
||||||
await loadDevices();
|
await loadDevices();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
window.dispatchRtcSignal = function(rawJson) {
|
||||||
|
handleRtcSignal(rawJson);
|
||||||
|
return "ok";
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user