如何在MAUI中创建WebView并捕获WebSocket消息?
在MAUI WebView中捕获WebSocket消息
MAUI的WebView本身没有原生提供捕获WebSocket消息的API,核心解决思路是注入自定义JavaScript脚本,拦截WebSocket的发送方法和接收事件,再通过JS与C#的交互机制将消息传回MAUI应用。以下是具体实现步骤:
1. 配置WebView并启用JS交互
首先在XAML中定义WebView,绑定导航完成事件:
<WebView x:Name="TargetWebView" Source="https://your-socket-connected-url.com" Navigated="OnWebViewNavigated" />
2. 注入WebSocket拦截脚本
在WebView导航完成后,注入脚本重写全局的WebSocket构造函数,拦截消息的收发动作:
private void OnWebViewNavigated(object sender, WebNavigatedEventArgs e) { // 根据平台生成对应脚本(Android/iOS的JS消息传递API不同) string injectScript = GetWebSocketInterceptorScript(); if (!string.IsNullOrEmpty(injectScript)) { _ = TargetWebView.EvaluateJavaScriptAsync(injectScript); } } private string GetWebSocketInterceptorScript() { #if ANDROID return @" // 保存原生WebSocket构造函数 const OriginalWebSocket = window.WebSocket; window.WebSocket = function(url, protocols) { const wsInstance = new OriginalWebSocket(url, protocols); // 拦截传出消息 const originalSend = wsInstance.send; wsInstance.send = function(data) { // 将消息发送到C#层 window.chrome.webview.postMessage(JSON.stringify({ type: 'outgoing', data: data, timestamp: new Date().toISOString() })); return originalSend.apply(this, arguments); }; // 监听传入消息 wsInstance.addEventListener('message', function(event) { window.chrome.webview.postMessage(JSON.stringify({ type: 'incoming', data: event.data, timestamp: new Date().toISOString() })); }); return wsInstance; }; "; #elif IOS || MACCATALYST return @" const OriginalWebSocket = window.WebSocket; window.WebSocket = function(url, protocols) { const wsInstance = new OriginalWebSocket(url, protocols); const originalSend = wsInstance.send; wsInstance.send = function(data) { window.webkit.messageHandlers.webview.postMessage(JSON.stringify({ type: 'outgoing', data: data, timestamp: new Date().toISOString() })); return originalSend.apply(this, arguments); }; wsInstance.addEventListener('message', function(event) { window.webkit.messageHandlers.webview.postMessage(JSON.stringify({ type: 'incoming', data: event.data, timestamp: new Date().toISOString() })); }); return wsInstance; }; "; #else return string.Empty; // Windows等其他平台可根据WebView实现调整 #endif }
3. 实现C#端的消息接收处理
针对不同平台,需要注册对应的脚本消息处理器,接收JS传递过来的WebSocket消息:
protected override void OnHandlerChanged() { base.OnHandlerChanged(); #if ANDROID var androidWebView = TargetWebView.Handler.PlatformView as Android.Webkit.WebView; if (androidWebView != null) { androidWebView.Settings.JavaScriptEnabled = true; androidWebView.SetWebChromeClient(new WebSocketMessageChromeClient()); } #elif IOS || MACCATALYST var wkWebView = TargetWebView.Handler.PlatformView as WebKit.WKWebView; if (wkWebView != null) { wkWebView.Configuration.UserContentController.AddScriptMessageHandler( new WebSocketMessageHandler(), "webview"); } #endif } // Android平台消息处理器 private class WebSocketMessageChromeClient : Android.Webkit.WebChromeClient { public override bool OnJsMessage(Android.Webkit.WebView view, string url, string message, Android.Webkit.JsResult result) { try { var wsMsg = System.Text.Json.JsonSerializer.Deserialize<WebSocketMessage>(message); // 这里可以处理消息,比如打印、存储或触发业务逻辑 Console.WriteLine($"[{wsMsg.Timestamp}] {wsMsg.Type}: {wsMsg.Data}"); } catch (Exception ex) { Console.WriteLine($"解析WebSocket消息失败: {ex.Message}"); } result.Confirm(); return true; } } // iOS平台消息处理器 private class WebSocketMessageHandler : WebKit.IWKScriptMessageHandler { public void DidReceiveScriptMessage(WebKit.WKUserContentController userContentController, WebKit.WKScriptMessage message) { try { var wsMsg = System.Text.Json.JsonSerializer.Deserialize<WebSocketMessage>(message.Body.ToString()); Console.WriteLine($"[{wsMsg.Timestamp}] {wsMsg.Type}: {wsMsg.Data}"); } catch (Exception ex) { Console.WriteLine($"解析WebSocket消息失败: {ex.Message}"); } } } // 消息模型类,用于序列化/反序列化 public class WebSocketMessage { public string Type { get; set; } // incoming/outgoing public string Data { get; set; } public string Timestamp { get; set; } }
关键注意事项
- 平台兼容性:Android使用
window.chrome.webview.postMessage传递消息,iOS使用window.webkit.messageHandlers.webview.postMessage,必须根据平台生成对应脚本。 - 全局拦截:脚本重写了全局的
WebSocket构造函数,页面中所有WebSocket实例(包括动态创建的)都会被监控。 - JavaScript权限:必须确保WebView已启用JavaScript(Android的
Settings.JavaScriptEnabled = true,iOS默认启用)。
内容的提问来源于stack exchange,提问作者sun yu
相关产品推荐
相关产品推荐

