Ruby - 用于循环连接的ThreadError

时间:2017-09-26 14:17:35

标签: ruby

我正在尝试套接字和线程,并遇到了一个问题,我认为我遇到了线程上限,但并不完全确定。

基本上我有<script> export default { created() { this.loadData(); }, data() { return { text: '', }; }, methods: { loadData() { this.$http.get("https://icanhazip.com") // This fails .then(xhr => this.text = xhr.data); } } }; </script> 打开TCPServer和server.rb连接到服务器。在服务器上,当用户连接时,我输出一些一般信息,然后想要开始读取从game.rb传递的数据。我相信我遇到的问题是我只是在每次循环执行时创建一个新线程,我想我已达到上限。我也不确定这是否是最佳做法。我想避免使用其他API,直到我掌握了基础知识,因此我尝试遵循https://github.com/sausheong/tanks中的代码。

server.rb

game.rb

game.rb

require 'socket'

# lsof -i :2000
# kill ID

class Server
  def initialize(host, port)
    puts "starting arena"

    @server = TCPServer.open(host, port)
    @sprites = Hash.new
    @players = Hash.new

    handle_connection(@server.accept)

  end

  def handle_connection(socket)
    _, port, host = socket.peeraddr
    user = "#{host}:#{port}"
    puts "#{user} has joined!"
    puts "------"

    loop do
      thread = Thread.start(socket) do |client|
        puts 'starting new thread'
        data = socket.readpartial(4096)
        data_array = data.split("\n")

        if data_array && data_array.any?
          begin
            data_array.each do |row|
              message = row.split("|")
              puts message
            end
          rescue Exception => exception
            puts "exception happened?"
            puts exception.inspect
          end
        end
      end
    end # end loop
  rescue EOFError => err
    puts "error"
    puts "Closing the connection. Bye!"
    socket.close
    puts err
  end # handle_connection end

end # class end

Server.new('localhost', 2000)

1 个答案:

答案 0 :(得分:0)

你的循环:(简化)

socket = @server.accept

loop do
  Thread.start(socket) do |client|
    # ...
  end
end

接受单个连接,然后尽可能快地创建新线程,将每个线程传递给相同的socket对象,这样所有线程就会同时开始从同一个套接字读取数据。

为避免这种情况,您必须将accept调用移动到循环中:

loop do
  socket = @server.accept

  Thread.start(socket) do |client|
    # ...
  end
end

或者简单地说:

loop do
  Thread.start(@server.accept) do |client|
    # ...
  end
end

accept立即阻止等待新连接,有效地暂停循环。建立连接后,它会创建一个新线程来处理该连接并重新开始循环。

可以在TCPServer的文档中找到类似的示例。