Reputation: 1576
I'm trying to achieve a socket server on Ruby with multiply rooms, where people can send chat messages to each other, for example.
The code is pretty simple: Main file:
require 'room'
require 'socket'
room = Room.new
### handle connections
Thread::abort_on_exception=true
server = TCPServer.open(2000) # Socket to listen on port 2000
puts 'Open socket at 2000 port'
loop { # Servers run forever
room.handle_player server.accept
}
room.rb
require 'player'
class Room
@players = []
attr_accessor :players
def initialize
end
def handle_player(connection)
puts ' New client connected!'
Thread.start(connection, self) do |client, room|
player = Player.new connection, room
@players.push player
end
end
def broadcast(message)
puts "Players is #{@players.class}" #NilClass !
end
end
player.rb
class Player
def initialize(connection, room)
@room = room
while line = connection.gets
puts 'got line ' + line
room.broadcast line
end
end
end
The problem is that when I call Room#broadcast from a player – it tells me that @players is nil, but it isn't! How that can be? I'm not sure I'm doing everything correct (my feelings tell me that player should not have direct link to room), but it simplifies the example.
Upvotes: 1
Views: 77
Reputation: 15954
This has nothing to do with threads.
You should put that initialization @players = []
into the initialize
of Room
.
The way you have it, you do not initialize an instance variable of your object but an instance variable of the class Room
.
Upvotes: 1
Reputation: 51171
You set @players
as a Room
's class instance variable.
Instead of this, you should put this in your initialize
method:
def initialize
@players = []
end
Upvotes: 1