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

使用WebSocketSharp获取验证码Token时遇平台不支持及对象已释放异常

问题描述

我尝试从Habbo的验证码接口获取Token,用WebSocketSharp搭建本地WebSocket服务配合Tampermonkey脚本传输,但出现以下错误:

29/08/2022 22:00:05|Error|QueueUserWorkItemCallbackDefaultContext.Execute|Operation is not supported on this platform.
29/08/2022 22:00:06|Fatal|<>c__DisplayClass48_0.<ReadBytesAsync>b__0|System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
at System.Net.Sockets.NetworkStream.<ThrowIfDisposed>g__ThrowObjectDisposedException|63_0()
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
at WebSocketSharp.Ext.<>c__DisplayClass48_0.<ReadBytesAsync>b__0(IAsyncResult ar)

Tampermonkey脚本代码:

// ==UserScript==
// @name         Captcha Service
// @namespace    mservice
// @version      1.0
// @description  no description
// @author       Moch
// @match        https://www.habbo.com.br/api/public/captcha*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    var socket = new WebSocket("ws://127.0.0.1:8080");
    socket.onopen = () => {
        const urlParams = new URLSearchParams(window.location.search);
        if (urlParams.has("token") && urlParams.get("token") !== "") {
            socket.send(urlParams.get("token"));
        }
    }
})();

C#服务端代码:

using WebSocketSharp;
using WebSocketSharp.Server;
public class Laputa : WebSocketBehavior
{
    protected override void OnMessage(MessageEventArgs e)
    {
        Console.WriteLine(e.Data);
    }
}

static void Main(string[] args)
{
    var wssv = new WebSocketServer("ws://127.0.0.1:8080");

    wssv.AddWebSocketService<Laputa>("/");
    wssv.Start();
    Console.ReadKey(true);
    wssv.Stop();
}

已尝试切换至WebSocketSharp-netstandard和WebSocketSharkFork,错误依旧。


解决方案

1. 平台兼容性问题

第一个错误Operation is not supported on this platform说明WebSocketSharp在当前运行的.NET平台上存在API兼容问题,比如旧版本对异步IO的处理和.NET Core/.NET 5+的网络栈不兼容。

解决办法:

  • 改用.NET原生的System.Net.WebSockets实现,兼容性更好。示例服务端代码:
    using System;
    using System.Net;
    using System.Net.WebSockets;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    class Program
    {
        static async Task Main(string[] args)
        {
            var listener = new HttpListener();
            listener.Prefixes.Add("http://127.0.0.1:8080/");
            listener.Start();
            Console.WriteLine("WebSocket服务已启动,等待连接...");
    
            while (true)
            {
                var context = await listener.GetContextAsync();
                if (context.Request.IsWebSocketRequest)
                {
                    var webSocketContext = await context.AcceptWebSocketAsync(null);
                    _ = HandleWebSocketConnection(webSocketContext.WebSocket);
                }
                else
                {
                    context.Response.StatusCode = 400;
                    context.Response.Close();
                }
            }
        }
    
        private static async Task HandleWebSocketConnection(WebSocket webSocket)
        {
            var buffer = new byte[1024 * 4];
            WebSocketReceiveResult result;
            try
            {
                do
                {
                    result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                    var message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                    Console.WriteLine("收到Token: " + message);
                } while (!result.CloseStatus.HasValue);
    
                await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
            }
            catch (Exception ex)
            {
                Console.WriteLine("连接异常: " + ex.Message);
                if (webSocket.State == WebSocketState.Open)
                {
                    await webSocket.CloseAsync(WebSocketCloseStatus.InternalServerError, "服务器异常", CancellationToken.None);
                }
            }
            finally
            {
                webSocket.Dispose();
            }
        }
    }
    

2. 连接过早关闭问题

第二个错误Cannot access a disposed object: System.Net.Sockets.NetworkStream通常是因为WebSocket连接在异步操作完成前就被释放了。原Tampermonkey脚本发送完Token后没有保持连接,浏览器可能主动关闭连接,导致服务端异步读取失败。

解决办法:

  • 修改脚本,发送完Token后延迟关闭连接,或者添加错误/关闭事件处理:
    // ==UserScript==
    // @name         Captcha Service
    // @namespace    mservice
    // @version      1.0
    // @description  no description
    // @author       Moch
    // @match        https://www.habbo.com.br/api/public/captcha*
    // @grant        none
    // ==/UserScript==
    
    (function () {
        'use strict';
    
        var socket = new WebSocket("ws://127.0.0.1:8080");
        socket.onopen = () => {
            const urlParams = new URLSearchParams(window.location.search);
            if (urlParams.has("token") && urlParams.get("token") !== "") {
                socket.send(urlParams.get("token"));
                // 延迟1秒关闭,确保服务端接收完成
                setTimeout(() => socket.close(), 1000);
            }
        };
    
        socket.onerror = (error) => {
            console.error("WebSocket错误:", error);
        };
    
        socket.onclose = (event) => {
            console.log("连接关闭:", event.code, event.reason);
        };
    })();
    

3. 替代第三方库

如果坚持用第三方库,推荐使用Fleck,它是轻量且兼容性更好的WebSocket服务端库:

  • 安装NuGet包:Install-Package Fleck
  • 示例代码:
    using Fleck;
    
    class Program
    {
        static void Main(string[] args)
        {
            var server = new WebSocketServer("ws://127.0.0.1:8080");
            server.Start(socket =>
            {
                socket.OnOpen = () => Console.WriteLine("客户端已连接");
                socket.OnMessage = message => Console.WriteLine("收到Token: " + message);
                socket.OnClose = () => Console.WriteLine("客户端已断开");
                socket.OnError = error => Console.WriteLine("错误: " + error);
            });
    
            Console.ReadKey(true);
            server.Dispose();
        }
    }
    

内容的提问来源于stack exchange,提问作者PercivallAkihiko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:01:13