简体   繁体   English

红宝石中的TCPServer,代码被卡住

[英]TCPServer in ruby, Code is stuck

im building a small game in ruby to practice programming, so far everything has went well but im trying to implement multiplayer support, i can connect to the server and i can send information but when I try to read form the server it just freezes and my screen goes completely black. 我用红宝石制作了一个小游戏来练习编程,到目前为止一切都进展顺利,但是我想实现多人支持,我可以连接到服务器并且可以发送信息,但是当我尝试从服务器读取信息时,它就会冻结并且我屏幕完全变黑。 and i cant find the cause, ive read the documentation for the gem im using for TCP and i dont know, maybe i missed something, but if any of you have some insight I would really appreciate it 我找不到原因,我已经阅读了用于TCP的gem im的文档,我不知道,也许我错过了一些东西,但是如果你们有什么见识,我将非常感谢

heres the repo if this code isnt enough 如果此代码不够,请使用此仓库

https://github.com/jaypitti/ruby-2d-gosu-game https://github.com/jaypitti/ruby-2d-gosu-game

heres the client side code 这是客户端代码

class Client
  include Celluloid::IO
  def initialize(server, port)
    begin
      @socket = TCPSocket.new(server, port)
    rescue
      $error_message = "Cannot find game server."
    end
  end
  def send_message(message)
    @socket.write(message) if @socket
  end
  def read_message
    @socket.readpartial(4096) if @socket
  end
end

heres the gameserver 这是游戏服务器

require 'celluloid/autostart'
require 'celluloid/io'
class Server
  include Celluloid::IO
  finalizer :shutdown
  def initialize(host, port)
    puts "Starting Server on #{host}:#{port}."
    @server = TCPServer.new(host, port)
    @objects = Hash.new
    @players = Hash.new
    async.run
  end
  def shutdown
    @server.close if @server
  end
  def run
    loop { async.handle_connection @server.accept }
  end
  def handle_connection(socket)
    _, port, host = socket.peeraddr
    user = "#{host}:#{port}"
    puts "#{user} has joined the arena."
    loop do
      data = socket.readpartial(4096)
      data_array = data.split("\n")
      if data_array and !data_array.empty?
        begin
          data_array.each do |row|
            message = row.split("|")
            if message.size == 10
              case message[0] 
              when 'obj'
                @players[user] = message[1..9] unless @players[user]
                @objects[message[1]] = message[1..9]
              when 'del'
                @objects.delete message[1]
              end
            end
            response = String.new
            @objects.each_value do |obj|
              (response << obj.join("|") << "\n") if obj
            end
            socket.write response
          end
        rescue Exception => exception
          puts exception.backtrace
        end
      end # end data
    end # end loop
  rescue EOFError => err
    player = @players[user]
    puts "#{player[3]} has left"
    @objects.delete player[0]
    @players.delete user
    socket.close
  end
end
server, port = ARGV[0] || "0.0.0.0", ARGV[1] || 1234
supervisor = Server.supervise(server, port.to_i)
trap("INT") do
  supervisor.terminate
  exit
end
sleep

First of all you should not be rescuing Exception all over the place. 首先,您不应该在所有地方拯救Exception Wrapping long begin rescue blocks around nested iterators is begging for trouble. 在嵌套的迭代器周围包装长期的抢救块正在乞求麻烦。

It sounds like a threading issues, memory and/or CPU but that's just a guess. 听起来像是线程问题,内存和/或CPU,但这只是一个猜测。 Try to monitor your resources or use some performance checking gems. 尝试监视您的资源或使用一些性能检查工具。 But for the love of Satoshi Nakamoto, please write some test coverage and see your methods fail miserably, then fix them! 但是对于中本聪(Satoshi Nakamoto)的热爱,请写一些测试报道,看看您的方法惨遭失败,然后修复它们!

Some of these may help: 其中一些可能会有所帮助:

group :development do
  gem 'bullet', require: false
  gem 'flamegraph', require: false
  gem 'memory_profiler', require: false
  gem 'rack-mini-profiler', require: false
  gem 'seed_dump'
  gem 'stackprof', require: false
  gem 'traceroute', require: false
end

it just freezes and my screen goes completely black. 它只是死机了,我的屏幕变成了全黑。 and i cant find the cause 我找不到原因

A good trick you can look at is attaching to your process with either rbspy or rbtrace to see that is going on when it is stuck. 您可以看到的一个不错的技巧是使用rbspyrbtrace将其附加到您的进程中,以查看卡住时进程是否继续进行。

You can also try first reducing dependencies here a bit and doing this with a simple threadpool prior to going full async with celluloid or event machine. 您也可以先尝试在此处稍微减少依赖关系,然后在使用赛璐璐或事件机器完全异步之前,使用简单的线程池进行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM