我正在尝试套接字和线程,并遇到了一个问题,我认为我遇到了线程上限,但并不完全确定。
基本上我有<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)
答案 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
的文档中找到类似的示例。