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

Windows 10下Async::WebSocket无法连接,Stream Deck Ruby SDK开发受阻

Windows 10下Ruby Async::WebSocket连接Stream Deck失败的解决方案

问题背景

我正在为Stream Deck开发Ruby SDK——Stream Deck是一款类似高级硬件AutoHotkey的设备,支持为按钮自定义图标和功能,还能通过目录无限扩展管理按钮。它提供语言无关的API,启动插件时会传入-port、-pluginUUID、-registerEvent、-info参数,插件需要在指定端口的localhost上建立WebSocket连接,连接后发送包含指定事件和UUID的JSON字符串完成注册。

当前遇到的问题:

  • Ruby 3.0.5环境下,参数解析和控制台输出正常,但WebSocket连接后程序挂起,无法正常通信
  • RubyInstaller 3.1.2环境下程序直接崩溃,报错:
    0.0s     warn: Async::Task [oid=0x280] [ec=0x294] [pid=32436] [2022-12-13 00:36:46 -0500]
                 | Task may have ended with unhandled exception.
                 |   Errno::EBADF: Bad file descriptor
                 |   → <internal:io> 63
                 |     C:/Ruby31-x64/lib/ruby/gems/3.1.0/gems/io-event-1.1.4/lib/io/event/selector/select.rb 206
    
  • WSL环境下修改为硬编码端口和UUID后,能正常与Stream Deck通信,推测是Windows平台下Async相关模块的兼容性问题

解决方案1:替换为非Async的WebSocket客户端

Async库在Windows平台的IO事件处理存在兼容性问题,改用faye-websocket(基于EventMachine)可以规避该问题,稳定性更好:

  1. 安装依赖:

    gem install faye-websocket eventmachine
    
  2. 替换测试脚本:

    #!/usr/bin/env ruby
    require "json"
    require "faye/websocket"
    require "eventmachine"
    
    # 解析启动参数
    _, port, _, UUID, _, REGISTER_EVENT, _, *info = ARGV
    PORT = port.to_i
    INFO = JSON.parse(info.join(" "))
    
    # 调试输出(确认参数正确)
    p PORT
    p UUID
    p REGISTER_EVENT
    p INFO
    
    EventMachine.run do
      # 建立WebSocket连接
      ws = Faye::WebSocket::Client.new("ws://localhost:#{PORT}")
    
      ws.on :open do |event|
        puts "Opened!"
        # 发送注册消息
        ws.send({ event: REGISTER_EVENT, uuid: UUID }.to_json)
      end
    
      ws.on :message do |event|
        puts "Message:"
        puts event.data
      end
    
      ws.on :close do |event|
        puts "Closed: #{event.code} - #{event.reason}"
        ws = nil
        EventMachine.stop
      end
    
      ws.on :error do |event|
        puts "Error: #{event.message}"
      end
    end
    

解决方案2:调整Async库的使用方式(针对Ruby 3.0.5)

如果坚持使用Async库,可以尝试以下调整修复Windows平台的兼容性问题:

  1. 强制使用兼容的IO选择器
    在代码开头添加环境变量,指定使用poll选择器(避免Windows下select调用的问题):

    ENV['IO_EVENT_SELECTOR'] = 'poll'
    

    若安装了io-event-win32 gem,也可以指定Windows专属选择器:

    gem install io-event-win32
    

    然后设置:

    ENV['IO_EVENT_SELECTOR'] = 'win32'
    
  2. 修复协议并添加错误处理
    显式使用ws://协议(而非http://),并添加异常捕获避免程序崩溃:

    #!/usr/bin/env ruby
    require "json"
    require "async/websocket/client"
    require "async/http/endpoint"
    
    # 指定兼容的IO选择器
    ENV['IO_EVENT_SELECTOR'] = 'poll'
    
    include Async
    include Async::HTTP
    
    # 解析参数
    _, port, _, UUID, _, REGISTER_EVENT, _, *info = ARGV
    PORT = port.to_i
    INFO = JSON.parse info.join(" ")
    
    p PORT
    p UUID
    p REGISTER_EVENT
    p INFO
    
    Async do |task|
      begin
        # 显式使用ws协议
        WebSocket::Client.connect(Endpoint.parse "ws://localhost:#{PORT}") do |ws|
          ws.write({ event: REGISTER_EVENT, uuid: UUID }.to_json)
          ws.flush
          puts "Opened!"
    
          while msg = ws.read
            puts "Message:"
            puts msg
          end
        end
      rescue Errno::EBADF => e
        puts "Connection failed: #{e.message}"
        # 可添加重连逻辑或退出
      end
    end
    

解决方案3:使用Ruby 3.1+标准库WebSocket客户端

Ruby 3.1及以上版本标准库内置了websocket-client-simple,无需额外依赖,兼容性更佳:

#!/usr/bin/env ruby
require "json"
require "websocket-client-simple"

# 解析参数
_, port, _, UUID, _, REGISTER_EVENT, _, *info = ARGV
PORT = port.to_i
INFO = JSON.parse(info.join(" "))

p PORT
p UUID
p REGISTER_EVENT
p INFO

# 建立WebSocket连接
ws = WebSocket::Client::Simple.connect "ws://localhost:#{PORT}"

ws.on :open do
  puts "Opened!"
  ws.send({ event: REGISTER_EVENT, uuid: UUID }.to_json)
end

ws.on :message do |msg|
  puts "Message:"
  puts msg.data
end

ws.on :close do |e|
  puts "Closed: #{e.code} #{e.reason}"
  exit 1
end

ws.on :error do |e|
  puts "Error: #{e.message}"
end

# 保持程序运行
loop do
  sleep 1
end

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 12:15:37