Base TCP server class. You must subclass GenericServer and provide a run method.
Creates a new generic server from config. The default
configuration comes from default.
# File webrick/server.rb, line 94
def initialize(config={}, default=Config::General)
@config = default.dup.update(config)
@status = :Stop
@config[:Logger] ||= Log::new
@logger = @config[:Logger]
@tokens = SizedQueue.new(@config[:MaxClients])
@config[:MaxClients].times{ @tokens.push(nil) }
webrickv = WEBrick::VERSION
rubyv = "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
@logger.info("WEBrick #{webrickv}")
@logger.info("ruby #{rubyv}")
@listeners = []
@shutdown_pipe = nil
unless @config[:DoNotListen]
if @config[:Listen]
warn(":Listen option is deprecated; use GenericServer#listen")
end
listen(@config[:BindAddress], @config[:Port])
if @config[:Port] == 0
@config[:Port] = @listeners[0].addr[1]
end
end
end
Retrieves key from the configuration
# File webrick/server.rb, line 124
def [](key)
@config[key]
end
Adds listeners from address and port to the
server. See WEBrick::Utils.create_listeners
for details.
# File webrick/server.rb, line 132
def listen(address, port)
@listeners += Utils::create_listeners(address, port, @logger)
setup_shutdown_pipe
end
You must subclass GenericServer and implement #run which accepts a TCP client socket
# File webrick/server.rb, line 245
def run(sock)
@logger.fatal "run() must be provided by user."
end
Shuts down the server and all listening sockets. New listeners must be provided to restart the server.
# File webrick/server.rb, line 227
def shutdown
stop
shutdown_pipe = @shutdown_pipe # another thread may modify @shutdown_pipe.
if shutdown_pipe
if !shutdown_pipe[1].closed?
begin
shutdown_pipe[1].close
rescue IOError # closed by another thread.
end
end
end
end
Starts the server and runs the block for each connection.
This method does not return until the server is stopped from a signal
handler or another thread using stop or shutdown.
If the block raises a subclass of StandardError the exception is logged and ignored. If an IOError or Errno::EBADF exception is raised the exception is ignored. If an Exception subclass is raised the exception is logged and re-raised which stops the server.
To completely shut down a server call shutdown from ensure:
server = WEBrick::GenericServer.new # or WEBrick::HTTPServer.new begin server.start ensure server.shutdown end
# File webrick/server.rb, line 158
def start(&block)
raise ServerError, "already started." if @status != :Stop
server_type = @config[:ServerType] || SimpleServer
server_type.start{
@logger.info "#{self.class}#start: pid=#{$$} port=#{@config[:Port]}"
call_callback(:StartCallback)
shutdown_pipe = @shutdown_pipe
thgroup = ThreadGroup.new
@status = :Running
begin
while @status == :Running
begin
if svrs = IO.select([shutdown_pipe[0], *@listeners], nil, nil, 2.0)
if svrs[0].include? shutdown_pipe[0]
break
end
svrs[0].each{|svr|
@tokens.pop # blocks while no token is there.
if sock = accept_client(svr)
sock.do_not_reverse_lookup = config[:DoNotReverseLookup]
th = start_thread(sock, &block)
th[:WEBrickThread] = true
thgroup.add(th)
else
@tokens.push(nil)
end
}
end
rescue Errno::EBADF, Errno::ENOTSOCK, IOError => ex
# if the listening socket was closed in GenericServer#shutdown,
# IO::select raise it.
rescue StandardError => ex
msg = "#{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}"
@logger.error msg
rescue Exception => ex
@logger.fatal ex
raise
end
end
ensure
cleanup_shutdown_pipe(shutdown_pipe)
cleanup_listener
@status = :Shutdown
@logger.info "going to shutdown ..."
thgroup.list.each{|th| th.join if th[:WEBrickThread] }
call_callback(:StopCallback)
@logger.info "#{self.class}#start done."
@status = :Stop
end
}
end
Commenting is here to help enhance the documentation. For example, code samples, or clarification of the documentation.
If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.
If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.
If you want to help improve the Ruby documentation, please visit Documenting-ruby.org.