cserver.rb 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. require 'tempfile'
  2. require 'fiber'
  3. require_relative '../monolog'
  4. require 'celluloid/io'
  5. require 'celluloid/autostart'
  6. Celluloid.task_class = Celluloid::Task::Threaded
  7. module Woe
  8. class Server
  9. include Monolog
  10. include Celluloid::IO
  11. finalizer :shutdown
  12. def initialize(host = 'localhost', port =7000, logname="woe.log")
  13. Monolog.setup_all(logname)
  14. # Celluloid.logger = self
  15. @port = port
  16. # Keep an overall record of the client IDs allocated
  17. # and the lines of chat
  18. @client_id = 0
  19. @clients = {}
  20. @tick_id = 0
  21. @host = host
  22. p "Server listening on #@host port #@port"
  23. @server = Celluloid::IO::TCPServer.new(@host, @port)
  24. async.run
  25. end
  26. def get_free_client_id
  27. cli = 0
  28. @clients.each do |client|
  29. return cli if client.nil?
  30. cli += 1
  31. end
  32. return cli
  33. end
  34. def run
  35. @busy = true
  36. p "Server main loop starts."
  37. while @busy
  38. begin
  39. p "Accepting"
  40. socket = @server.accept
  41. p socket
  42. async.handle_connection(socket)
  43. rescue
  44. p "exception #{$!}"
  45. @busy = false
  46. end
  47. end
  48. end
  49. def handle_connection(socket)
  50. p "Connecting socket."
  51. _, port, host = socket.peeraddr
  52. p "*** Received connection from #{host}:#{port}"
  53. client_id = get_free_client_id
  54. client = Client.new(self, client_id, socket)
  55. @clients[client_id] = client
  56. begin
  57. client.run
  58. rescue EOFError
  59. p "*** #{host}:#{port} disconnected"
  60. ensure
  61. disconnect(client.id)
  62. socket.close
  63. end
  64. end
  65. def disconnect(id)
  66. log_info("Server disconnecting client #{@id}")
  67. @clients.delete(id)
  68. end
  69. def clients_stopped?
  70. end
  71. def reload
  72. log_info("Server reload")
  73. broadcast("Server reload NOW!\n")
  74. begin
  75. load 'lib/telnet.rb'
  76. load 'lib/woe/client.rb'
  77. load 'lib/woe/server.rb'
  78. broadcast("Server reloaded OK.\n")
  79. rescue Exception => ex
  80. bt = ex.backtrace.join("\n")
  81. log_error("Server reload failed: #{ex}: #{bt}")
  82. broadcast("Server reload exception #{ex}: #{bt}!\n")
  83. end
  84. end
  85. def stop
  86. log_info("Server stop")
  87. shutdown
  88. log_info("Server stop OK.")
  89. end
  90. def broadcast(msg)
  91. @clients.each do |id, client|
  92. client.send_data(msg)
  93. end
  94. end
  95. def shutdown
  96. log_info("Shuting down server.")
  97. @busy = false
  98. @server.close if @server
  99. end
  100. end
  101. end