You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 18:13:20