ruby - ruby中的TCPServer,代码卡住了
问题描述
我正在用 ruby 构建一个小游戏来练习编程,到目前为止一切顺利,但我正在尝试实现多人游戏支持,我可以连接到服务器并且我可以发送信息但是当我尝试从服务器读取它时它只是冻结并且我的屏幕完全变黑。我找不到原因,我阅读了用于 TCP 的 gem 的文档,但我不知道,也许我错过了一些东西,但如果你们中有人有一些见识,我将不胜感激
如果这段代码不够的话,这里是 repo
https://github.com/jaypitti/ruby-2d-gosu-game
这是客户端代码
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
这是游戏服务器
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
解决方案
首先,你不应该到处救援Exception
。在嵌套迭代器周围包裹长的开始救援块是在自找麻烦。
这听起来像是线程问题、内存和/或 CPU,但这只是一个猜测。尝试监控您的资源或使用一些性能检查 gem。但是为了中本聪的爱,请写一些测试覆盖率,看看你的方法失败得很惨,然后修复它们!
其中一些可能会有所帮助:
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
推荐阅读
- python - 如何使用 pandas 同时从 csv 中提取两个值?(两列,同一行)
- android - 如何创建这种类型的布局
- javascript - 为 Gcloud AutoML Vision API 验证 Javascript 程序
- mysql - MYSQL - 从每个不同的 id 获取最后一个结果
- gradle - 如何从 Gradle 调用 sbt 任务?
- javascript - 在 d3.js 中制作条形图。如何将单个对象中的值放入一个栏中?
- swift - 单元测试 - 未在构建设置中显示 TEST_TARGET_NAME
- jquery - 在点击事件上压缩 jQuery
- typescript - 导入默认命名空间 - 为什么我得到“未定义”?
- python - python的小数点