forked from zammad/zammad
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwebsocket-server.rb
executable file
·130 lines (108 loc) · 3.33 KB
/
websocket-server.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#!/usr/bin/env ruby
# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
begin
load File.expand_path('../bin/spring', __dir__)
rescue LoadError => e
raise if e.message.exclude?('spring')
end
dir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
Dir.chdir dir
require 'bundler'
require File.join(dir, 'config', 'environment')
require 'eventmachine'
require 'em-websocket'
require 'json'
require 'fileutils'
require 'optparse'
require 'daemons'
def before_fork
# remember open file handles
@files_to_reopen = []
ObjectSpace.each_object(File) do |file|
@files_to_reopen << file if !file.closed?
end
end
def after_fork(dir)
Dir.chdir dir
# Re-open file handles
@files_to_reopen.each do |file|
file.reopen file.path, 'a+'
file.sync = true
end
# Spring redirects STDOUT and STDERR to /dev/null
# before we get here. This causes the `reopen` lines
# below to fail because the handles are already
# opened for write
if defined?(Spring)
$stdout.close
$stderr.close
end
$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
# Look for -o with argument, and -I and -D boolean arguments
@options = {
p: 6042,
b: '0.0.0.0',
s: false,
v: false,
d: false,
k: '/path/to/server.key',
c: '/path/to/server.crt',
i: "#{dir}/tmp/pids/websocket.pid"
}
OptionParser.new do |opts|
opts.banner = 'Usage: websocket-server.rb start|stop [options]'
opts.on('-d', '--daemon', 'start as daemon') do |d|
@options[:d] = d
end
opts.on('-v', '--verbose', 'enable debug messages') do |d|
@options[:v] = d
end
opts.on('-p', '--port [OPT]', 'port of websocket server') do |p|
@options[:p] = p
end
opts.on('-b', '--bind [OPT]', 'bind address') do |b|
@options[:b] = IPAddr.new(b).to_s
end
opts.on('-s', '--secure', 'enable secure connections') do |s|
@options[:s] = s
end
opts.on('-i', '--pid [OPT]', 'pid, default is tmp/pids/websocket.pid') do |i|
@options[:i] = i
end
opts.on('-k', '--private-key [OPT]', '/path/to/server.key for secure connections') do |k|
options[:tls_options] ||= {}
options[:tls_options][:private_key_file] = k
end
opts.on('-c', '--certificate [OPT]', '/path/to/server.crt for secure connections') do |c|
options[:tls_options] ||= {}
options[:tls_options][:cert_chain_file] = c
end
end.parse!
if ARGV[0] != 'start' && ARGV[0] != 'stop'
puts "Usage: #{File.basename(__FILE__)} start|stop [options]"
exit
end
if ARGV[0] == 'stop'
pid = File.read(@options[:i]).to_i
puts "Stopping websocket server (pid: #{pid})"
# 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)
exit
end
if ARGV[0] == 'start' && @options[:d]
puts "Starting websocket server on #{@options[:b]}:#{@options[:p]} (secure: #{@options[:s]}, pidfile: #{@options[:i]})"
# 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)
end
WebsocketServer.run(@options)