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

Ruby中Socket.tcp客户端通过指定机器代理的实现问询

在Sidekiq Worker里单独代理Socket连接的完美方案

嘿,刚好我之前踩过类似的坑,你提到的Net::SSH完全能解决你的问题——而且刚好能实现「只代理当前Worker代码,不影响服务器其他进程」的需求,比你之前试的ruby-proxifier更贴合场景。

核心思路:用Net::SSH创建临时隔离的本地代理

Net::SSH支持本地动态SOCKS转发,简单来说就是在你的Worker进程里临时开一个小代理,Worker跑完这个代理就自动消失,完全不会干扰服务器上的其他代码。结合ruby-proxifier的块级代理,就能精准控制只有Worker里的Socket连接走代理。

步骤1:先搞定依赖

确保Gemfile里有这两个包:

gem 'net-ssh'
gem 'ruby-proxifier' # 如果你用SOCKS动态代理的话需要它

然后跑bundle install就行。

步骤2:Sidekiq Worker的具体实现

我给你写个完整的Worker示例,注释都标清楚了:

class ProxySocketWorker
  include Sidekiq::Worker

  def perform(target_host, target_port, proxy_host, proxy_user, proxy_key_path)
    # 先通过Net::SSH连到你的代理机器,建立动态端口转发
    Net::SSH.start(proxy_host, proxy_user, keys: [proxy_key_path]) do |ssh|
      # 在本地开一个1080端口作为临时SOCKS代理(怕冲突的话可以用0让系统随机分配)
      local_socks_port = ssh.forward.local(1080, '0.0.0.0', 0, handler: Net::SSH::Proxy::SOCKS5.new('localhost', 1080))

      # 用ruby-proxifier的块语法,只有这个块里的代码会走代理!
      Proxifier::Proxy("socks5://localhost:#{local_socks_port}") do
        # 这里就是你的Socket逻辑,完全走代理
        socket = Socket.tcp(target_host, target_port, connect_timeout: 10)
        # 比如发送数据、接收响应之类的操作...
        socket.write("Hello via proxy!\n")
        response = socket.gets
        puts response
        socket.close
      end
    end
    # 到这里,SSH连接关闭,临时代理也没了,其他代码不受影响
  end
end

关键细节要注意

  • 完全隔离:这个临时代理是绑定在当前Worker线程的,Worker执行完,SSH连接断开,代理直接销毁,服务器上其他进程的网络请求该怎么走还是怎么走。
  • 块级代理控制:ruby-proxifier的Proxifier::Proxy() do ... end是局部生效的,块外的代码不会被代理,完美满足你只代理Worker代码的需求。
  • 端口冲突解决:如果1080端口可能被占用,把1080换成0,系统会自动分配一个空闲端口,然后用local_socks_port变量拿到这个端口号就行。

更轻量的替代方案(不用ruby-proxifier)

如果你只是要连固定的目标主机和端口,完全可以不用ruby-proxifier,直接用Net::SSH的静态端口转发:

class ProxySocketWorker
  include Sidekiq::Worker

  def perform(target_host, target_port, proxy_host, proxy_user, proxy_key_path)
    Net::SSH.start(proxy_host, proxy_user, keys: [proxy_key_path]) do |ssh|
      # 把本地9999端口转发到目标机器的target_port
      ssh.forward.local(9999, target_host, target_port)
      
      # 直接连本地9999,流量会自动通过代理机器转发到目标主机
      socket = Socket.tcp('localhost', 9999, connect_timeout: 10)
      # 后续操作...
    end
  end
end

这个方案更简单,没有额外依赖,适合固定目标的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:56:41