Refactor and test IPv6 support in websocket server

This commit is contained in:
Muhammad Nuzaihan 2018-03-16 02:21:04 +08:00 committed by Ryan Lue
parent 57c1124a42
commit cd4dc311ae
2 changed files with 57 additions and 18 deletions

View file

@ -5,7 +5,7 @@ $LOAD_PATH << './lib'
require 'rubygems'
# load rails env
dir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
dir = File.expand_path('..', __dir__)
Dir.chdir dir
RAILS_ENV = ENV['RAILS_ENV'] || 'development'
@ -38,8 +38,8 @@ def after_fork(dir)
file.sync = true
end
$stdout.reopen( "#{dir}/log/websocket-server_out.log", 'w')
$stderr.reopen( "#{dir}/log/websocket-server_err.log", 'w')
$stdout.reopen( "#{dir}/log/websocket-server_out.log", 'w').sync = true
$stderr.reopen( "#{dir}/log/websocket-server_err.log", 'w').sync = true
end
before_fork
@ -70,7 +70,7 @@ OptionParser.new do |opts|
@options[:p] = p
end
opts.on('-b', '--bind [OPT]', 'bind address') do |b|
@options[:b] = b
@options[:b] = IPAddr.new(b).to_s
end
opts.on('-s', '--secure', 'enable secure connections') do |s|
@options[:s] = s
@ -92,29 +92,29 @@ if ARGV[0] != 'start' && ARGV[0] != 'stop'
end
if ARGV[0] == 'stop'
puts "Stopping websocket server (pid:#{@options[:i]})"
pid = File.read(@options[:i]).to_i
puts "Stopping websocket server (pid: #{pid})"
# read pid
pid = File.open( @options[:i].to_s ).read
pid.gsub!(/\r|\n/, '')
# IMPORTANT: Use SIGTERM (15), not SIGKILL (9)
# Daemons.rb cleans up the PID file automatically on termination;
# SIGKILL ends the process immediately and bypasses cleanup.
# See https://major.io/2010/03/18/sigterm-vs-sigkill/ for more.
Process.kill(:SIGTERM, pid)
# kill
Process.kill( 9, pid.to_i )
exit
end
if ARGV[0] == 'start' && @options[:d]
puts "Starting websocket server on #{@options[:b]}:#{@options[:p]} (secure:#{@options[:s]},pid:#{@options[:i]})"
puts "Starting websocket server on #{@options[:b]}:#{@options[:p]} (secure: #{@options[:s]}, pidfile: #{@options[:i]})"
Daemons.daemonize
# Use Daemons.rb's built-in facility for generating PID files
Daemons.daemonize(
app_name: File.basename(@options[:i], '.pid'),
dir_mode: :normal,
dir: File.dirname(@options[:i])
)
after_fork(dir)
# create pid file
daemon_pid = File.new(@options[:i].to_s, 'w')
daemon_pid.sync = true
daemon_pid.puts(Process.pid.to_s)
daemon_pid.close
end
@clients = {}

View file

@ -0,0 +1,39 @@
require 'spec_helper'
require 'timeout'
describe 'websocket-server' do
# Why not Rails.root.join here?
# Because it's not avaialable in this spec (no 'rails_helper' = faster start-up)
let(:app_root) { File.expand_path('../..', __dir__) }
let(:ws_server) { File.expand_path('script/websocket-server.rb', app_root) }
let(:pidfile) { File.expand_path('tmp/pids/websocket.pid', app_root) }
let(:output_log) { File.expand_path('log/websocket-server_out.log', app_root) }
let(:error_log) { File.expand_path('log/websocket-server_err.log', app_root) }
context 'with IPv6 bind address (via -b option)' do
# This error is raised for invalid bind addresses
let(:error_msg) { "`start_tcp_server': no acceptor" }
let(:ipv6_addr) { '::1/128' }
# Flush logs
before do
File.write(output_log, '')
File.write(error_log, '')
end
it 'starts up successfully' do
begin
system("#{ws_server} start -db #{ipv6_addr} >/dev/null 2>&1")
# Wait for daemon to start
Timeout.timeout(20, Timeout::Error, 'WebSocket Server startup timed out') do
loop { break if File.size(output_log) + File.size(error_log) > 0 }
end
expect(File.read(error_log)).not_to include(error_msg)
ensure
system("#{ws_server} stop >/dev/null 2>&1") if File.exist?(pidfile)
end
end
end
end