#!/usr/bin/ruby#======================================================================# * Session#----------------------------------------------------------------------# The thread for each individual user#======================================================================class Session attr_reader :socket #------------------------------------------------------------ # Initialize #------------------------------------------------------------ def initialize(socket) @socket = socket # Socket to client @timeout = Time.now.to_i + 120 # Time to time out (2 minutes) # Add to global session list $sessions.push(self) # Debug output puts "Connected to #{socket.addr[3]}" # Listening thread @listen = Thread.new do # Until socket closes until socket.eof? # Wait for command and data command, data = socket.gets.scan(/(\S+) (.*\n)/)[0] # Reset timeout when data is recieved @timeout = Time.now.to_i + 120 # Command handlers case command when 'SAY' say(data) end end # Disconnect disconnect('Socket closed') end # Main loop until @die # Timeout if necessary if Time.now.to_i >= @timeout disconnect('Ping timeout') end # Wait sleep(1) end end #------------------------------------------------------------ # Disconnect #------------------------------------------------------------ def disconnect(reason) # Remove from session list $sessions.delete(self) # Debug output puts "Disconnected from #{@socket.addr[3]} (#{reason})" # Kill update loop @die = true # Kill listening thread @listen.kill end #------------------------------------------------------------ # Say #------------------------------------------------------------ def say(message) # Send message to all sessions for session in $sessions unless session == self session.socket.write("#{@socket.addr[3]}: #{message}") end end # Debug output puts "#{@socket.addr[3]}: #{message}" endend#======================================================================# * Main#----------------------------------------------------------------------# Requires, server initialization, and main loop#======================================================================require 'net/http'# Start serverserver = TCPServer.new('localhost', 9090)# Debug outputputs 'Listening...'# Global session list$sessions = []# Debug threadsThread.abort_on_exception = true# Allow code from terminalThread.new do require 'eval'end# Connection handlerwhile (socket = server.accept) Thread.new do Session.new(socket) endend