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

.NET C#控制台实现事件驱动WebSocket(Stream Deck插件开发)

实现C#控制台程序的Elgato Stream Deck事件驱动WebSocket插件

可行方案:基于System.Net.WebSockets.ClientWebSocket实现事件驱动模型

System.Net.WebSockets.ClientWebSocket完全可以在C#控制台程序中使用,虽然它本身提供的是异步API而非原生事件驱动模型,但我们可以基于它封装出符合需求的事件触发逻辑,模拟Open、Message、Close、Error等事件。

核心实现思路

  • 封装一个WebSocket客户端类,内部维护ClientWebSocket实例,通过异步循环监听消息,在对应阶段触发自定义事件。
  • 定义对应场景的事件委托,覆盖连接建立、消息接收、连接关闭、错误触发四种核心场景。
  • 在连接成功后触发Open事件执行Stream Deck注册逻辑;收到消息时触发Message事件解析设备上报内容;连接关闭或出错时触发对应事件。

示例代码实现

using System;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

public class StreamDeckWebSocketClient
{
    // 定义事件委托
    public event Action OnOpen;
    public event Action<string> OnMessage;
    public event Action<WebSocketCloseStatus?, string> OnClose;
    public event Action<Exception> OnError;

    private ClientWebSocket _webSocket;
    private CancellationTokenSource _cts;

    public async Task ConnectAsync(Uri uri)
    {
        _webSocket = new ClientWebSocket();
        _cts = new CancellationTokenSource();

        try
        {
            await _webSocket.ConnectAsync(uri, _cts.Token);
            // 触发连接建立事件
            OnOpen?.Invoke();
            // 启动消息监听循环
            await ListenForMessagesAsync();
        }
        catch (Exception ex)
        {
            OnError?.Invoke(ex);
        }
        finally
        {
            await CloseAsync();
        }
    }

    private async Task ListenForMessagesAsync()
    {
        var buffer = new byte[1024 * 4];
        while (_webSocket.State == WebSocketState.Open)
        {
            try
            {
                var result = await _webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), _cts.Token);
                if (result.MessageType == WebSocketMessageType.Close)
                {
                    await _webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, _cts.Token);
                    OnClose?.Invoke(result.CloseStatus, result.CloseStatusDescription);
                    break;
                }

                var message = Encoding.UTF8.GetString(buffer, 0, result.Count);
                // 触发消息接收事件
                OnMessage?.Invoke(message);
            }
            catch (Exception ex)
            {
                OnError?.Invoke(ex);
                break;
            }
        }
    }

    public async Task SendMessageAsync(string message)
    {
        if (_webSocket.State != WebSocketState.Open)
            throw new InvalidOperationException("WebSocket连接未建立");

        var buffer = Encoding.UTF8.GetBytes(message);
        await _webSocket.SendAsync(new ArraySegment<byte>(buffer), WebSocketMessageType.Text, true, _cts.Token);
    }

    public async Task CloseAsync()
    {
        if (_webSocket.State == WebSocketState.Open)
        {
            await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "客户端主动关闭", CancellationToken.None);
        }
        _cts?.Cancel();
        _webSocket?.Dispose();
        _cts?.Dispose();
    }
}

使用示例

class Program
{
    static async Task Main(string[] args)
    {
        var wsClient = new StreamDeckWebSocketClient();
        // 绑定事件处理逻辑
        wsClient.OnOpen += () =>
        {
            Console.WriteLine("WebSocket连接已建立,执行Stream Deck注册...");
            // 在这里发送Stream Deck要求的注册消息
            // await wsClient.SendMessageAsync("{\"event\": \"register\", \"uuid\": \"你的插件UUID\"}");
        };

        wsClient.OnMessage += (message) =>
        {
            Console.WriteLine($"收到设备消息:{message}");
            // 按照Stream Deck API规范解析消息,处理对应事件
        };

        wsClient.OnClose += (status, description) =>
        {
            Console.WriteLine($"连接关闭:{status} - {description}");
        };

        wsClient.OnError += (ex) =>
        {
            Console.WriteLine($"连接出错:{ex.Message}");
        };

        // 替换为Stream Deck的实际WebSocket地址
        var streamDeckUri = new Uri("ws://localhost:2356");
        await wsClient.ConnectAsync(streamDeckUri);

        // 保持控制台程序运行
        Console.ReadLine();
        await wsClient.CloseAsync();
    }
}

关键说明

  • ClientWebSocket是.NET标准库组件,支持所有.NET平台(包括.NET Core/.NET 5+),完全适配控制台程序场景。
  • 上述封装通过异步监听循环,将原生异步API转换为事件驱动模式,完全匹配你需要的Open/Message事件触发需求。
  • 注册逻辑和消息解析可直接对接Elgato Stream Deck的官方API规范,将JSON消息反序列化为实体类处理即可。

内容的提问来源于stack exchange,提问作者Michael Kintscher they-them

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 09:21:01