【问题标题】:One TCPSocket, two threads一个 TCPSocket,两个线程
【发布时间】:2014-05-30 13:34:08
【问题描述】:

我需要为TCPSoket 客户端实现一个监听循环,它不会阻止向同一个套接字发送数据。

大概的结构是这样的:

class SocketWrapper
  def initialize
    @messages = []
    @socket = TCPSocket.open('192.168.0.25', 2000)
    Thread.new do
       loop do
          @messages.push @socket.read
       end
    end
  end

  def send_message(msg)
    @socket.write msg
  end

  def read_messages
    @messages.dup
    @messages.clear
  def
end

这个结构一切正常吗?

我需要在这里实现两个策略:

  1. response = send_request(request_data)
  2. 监听器 - 当传入的数据不是对我的请求的响应,而是我必须监听的异步数据时。

【问题讨论】:

  • 请记住,@socket.read 是一个阻塞调用,在大多数情况下会等到您从另一端关闭套接字。如果这不是您想要的通过套接字发送长度并使用read(n)。并按照答案中的建议使用Queue
  • 是不是说socket在一个线程等待传入数据时,就不能在其他线程发送数据了?是否有一些客户端套接字事件要订阅?

标签: ruby multithreading asynchronous tcpsocket


【解决方案1】:

Ruby 有一个专门为此设计的类 - Queue

class SocketWrapper
  def self.instance
    @inst ||= self.new
  end

  def initialize
    @messages = Queue.new
    @socket = TCPSocket.open('192.168.0.25', 2000)
    Thread.new do
       loop do
          @messages << @parse_message.nil? ? @socket.read : @parse_message.call(@socket.read)
       end
    end
  end

  def parse_message(&block)
    @parse_message = block
  end

  def send_message(msg)
    @socket.write msg
  end

  def read_messages
    result = []
    begin
      while message = @messages.pop(true)
        result << message
      end
    rescue ThreadError
      #raised if queue is empty
    end
    result
  def
end

在初始化器中:

SocketWrapper.instance.parse_message do |raw|
  JSON.parse(raw)
  # or any other awesome thing with raw
end

在控制器中:

SocketWrapper.instance.send_message('blah blah blah')

【讨论】:

  • 好的,我已经建立了这个类,把它放到初始化器中,这样它就可以在应用程序启动时启动,但是如何调用它的send_message方法——如何引用类实例?在初始化程序中分配的变量已留在初始化程序中并且超出范围。
  • 根据您的架构,您可以将其放在共享存储库中,甚至可以将其设置为 SocketWrapper 中的类成员 - 类似于 SocketWrapper.current
  • def self.instance @@instance end def self.init_instance @@instance = SocketWrapper.new end SocketWrapper.instance 始终为零。我做错了什么?
  • 你打电话给SocketWrapper.init_instance了吗?你不需要@@ - @ 就足够了
  • 问题是@@instance 中可能存在名称冲突。替换为@@inst。是的,你是对的,@ 就足够了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 2013-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多