swee 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +212 -0
- data/Rakefile +4 -0
- data/bin/swee +38 -0
- data/doc/tmp.rb +77 -0
- data/lib/swee.rb +5 -0
- data/lib/swee/app_executor.rb +152 -0
- data/lib/swee/config.rb +118 -0
- data/lib/swee/connection.rb +48 -0
- data/lib/swee/controller.rb +158 -0
- data/lib/swee/controller_filter.rb +67 -0
- data/lib/swee/daemonize.rb +17 -0
- data/lib/swee/engine.rb +201 -0
- data/lib/swee/exception.rb +2 -0
- data/lib/swee/helper.rb +29 -0
- data/lib/swee/installer.rb +58 -0
- data/lib/swee/lodder.rb +92 -0
- data/lib/swee/middlewaves/common_logger.rb +29 -0
- data/lib/swee/middlewaves/content_length.rb +21 -0
- data/lib/swee/middlewaves/reloader.rb +24 -0
- data/lib/swee/patches/logger.rb +15 -0
- data/lib/swee/routes.rb +46 -0
- data/lib/swee/server.rb +298 -0
- data/lib/swee/support.rb +79 -0
- data/lib/swee/swee_logger.rb +59 -0
- data/lib/swee/thin/headers.rb +40 -0
- data/lib/swee/thin/request.rb +162 -0
- data/lib/swee/thin/response.rb +177 -0
- data/lib/swee/version.rb +3 -0
- data/lib/swee/view.rb +36 -0
- data/lib/template/config.rb +38 -0
- data/lib/template/controllers/HomeController.rb +11 -0
- data/lib/template/public/404.html +66 -0
- data/lib/template/routes.rb +11 -0
- data/lib/template/todo_config.rb +75 -0
- data/lib/template/views/home/index.erb +2 -0
- metadata +164 -0
data/lib/swee/helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require "erb"
|
2
|
+
# require "cgi"
|
3
|
+
|
4
|
+
module Swee
|
5
|
+
|
6
|
+
module Helper
|
7
|
+
def raw text
|
8
|
+
text.html_safe
|
9
|
+
end
|
10
|
+
|
11
|
+
def image_tag
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
def form_for
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def tag(name, options = nil, open = false, escape = true)
|
20
|
+
|
21
|
+
"<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
|
22
|
+
end
|
23
|
+
|
24
|
+
def parse_tag_options options
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Swee
|
2
|
+
module Installer
|
3
|
+
module_function
|
4
|
+
def run proj_name
|
5
|
+
|
6
|
+
# 打印安装信息
|
7
|
+
puts "--------------- Swee 安装 -----------------"
|
8
|
+
proj_dir = "#{Dir.pwd}/#{proj_name}"
|
9
|
+
|
10
|
+
# 创建项目目录
|
11
|
+
if Dir.exist?(proj_dir)
|
12
|
+
puts "当前路径已存在#{proj_name}目录"
|
13
|
+
return
|
14
|
+
end
|
15
|
+
puts "#{proj_name}目录创建成功"
|
16
|
+
Dir.mkdir(proj_dir)
|
17
|
+
|
18
|
+
# 安装目录
|
19
|
+
app_path = proj_dir
|
20
|
+
["public","controllers","logs","models","tmp","views","views/home"].each do |dir|
|
21
|
+
_dir = app_path + "/#{dir}"
|
22
|
+
if Dir.exist?(_dir)
|
23
|
+
puts "#{_dir}目录已存在,略过..."
|
24
|
+
else
|
25
|
+
Dir.mkdir(_dir)
|
26
|
+
puts "#{_dir}目录成功创建"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# 安装 文件
|
31
|
+
["config.rb","routes.rb","public/404.html","controllers/HomeController.rb", "views/home/index.erb"].each do |_file|
|
32
|
+
file = app_path + "/#{_file}"
|
33
|
+
|
34
|
+
if File.exist?(file)
|
35
|
+
puts "#{file} 已经安装过了"
|
36
|
+
else
|
37
|
+
f = File.open(file,"w")
|
38
|
+
config_file = File.expand_path("../template/#{_file}",File.dirname(__FILE__))
|
39
|
+
f.write(File.read(config_file))
|
40
|
+
f.close
|
41
|
+
puts "#{file} 已经安装"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# 打印结束信息
|
46
|
+
puts "恭喜,全部安装完成"
|
47
|
+
puts "您可以先输入: swee s 来启动服务器"
|
48
|
+
puts "请打开config.rb 和 routes.rb 配置所需的参数"
|
49
|
+
puts "更多参数请输入: swee --help"
|
50
|
+
puts ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
|
51
|
+
puts "我们先启动一个欢迎页面"
|
52
|
+
puts "浏览器输入 http://localhost:3000 来访问欢迎页面吧"
|
53
|
+
puts "按 Ctrl + C 关闭服务"
|
54
|
+
puts ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
|
55
|
+
`cd #{proj_name} && swee s`
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/swee/lodder.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
module Swee
|
2
|
+
module Lodder
|
3
|
+
@@mtime_files_cache = {}
|
4
|
+
|
5
|
+
CACHE_FILE_MTIME_DIR = ["models","controllers"]
|
6
|
+
EXTENSION_NAMES = [".rb",".erb",".haml",".slim","ymal"]
|
7
|
+
|
8
|
+
module_function
|
9
|
+
|
10
|
+
def cache_file_mtime
|
11
|
+
CACHE_FILE_MTIME_DIR.each { |d| Lodder.search_app_file(d) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def mtime_files
|
15
|
+
@@mtime_files_cache
|
16
|
+
end
|
17
|
+
|
18
|
+
# 递归寻找目录下所有文件
|
19
|
+
# 保存为如下结构(用于 代码修改 reload)
|
20
|
+
# filename => mtime
|
21
|
+
def search_app_file dir
|
22
|
+
app_path = ENV["app_path"]
|
23
|
+
Dir.glob("#{app_path}/#{dir}/*") do |file|
|
24
|
+
if EXTENSION_NAMES.include? File.extname(file).downcase
|
25
|
+
@@mtime_files_cache[file] = File.mtime(file)
|
26
|
+
else
|
27
|
+
if File.directory?(file)
|
28
|
+
search_app_file(dir + "/" + file.split("/").last)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def base_require
|
35
|
+
require_relative './support'
|
36
|
+
require_relative './config'
|
37
|
+
# require_relative './application'
|
38
|
+
|
39
|
+
# patches
|
40
|
+
require_relative './patches/logger.rb'
|
41
|
+
|
42
|
+
# app
|
43
|
+
require_relative './routes'
|
44
|
+
require_relative './helper'
|
45
|
+
require_relative './controller_filter'
|
46
|
+
require_relative './controller'
|
47
|
+
require_relative './view'
|
48
|
+
require_relative './app_executor'
|
49
|
+
|
50
|
+
# middlewaves
|
51
|
+
require_relative './middlewaves/content_length'
|
52
|
+
require_relative './middlewaves/common_logger'
|
53
|
+
require_relative './middlewaves/reloader'
|
54
|
+
|
55
|
+
# thin
|
56
|
+
require_relative './thin/headers'
|
57
|
+
require_relative './thin/request'
|
58
|
+
require_relative './thin/response'
|
59
|
+
|
60
|
+
# server
|
61
|
+
require_relative './swee_logger'
|
62
|
+
require_relative './daemonize'
|
63
|
+
require_relative './connection'
|
64
|
+
require_relative './server'
|
65
|
+
require_relative './exception'
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
# 用户配置
|
70
|
+
def app_require
|
71
|
+
# require_relative './application'
|
72
|
+
begin
|
73
|
+
require File.expand_path('config', ENV["app_path"])
|
74
|
+
rescue LoadError
|
75
|
+
raise "未找到config.rb"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# 条件读取
|
80
|
+
def conditional_require
|
81
|
+
# 存在 AR 读取
|
82
|
+
unless Gem.find_files("active_record").empty?
|
83
|
+
require 'active_record'
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def all
|
88
|
+
conditional_require
|
89
|
+
base_require
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Rack
|
2
|
+
class CommonLogger
|
3
|
+
def initialize(app, logger=nil)
|
4
|
+
@app = app
|
5
|
+
@logger = logger
|
6
|
+
end
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def log(env, status, header, began_at)
|
11
|
+
now = Time.now
|
12
|
+
length = extract_content_length(header)
|
13
|
+
|
14
|
+
msg = FORMAT % [
|
15
|
+
env['HTTP_X_FORWARDED_FOR'] || env["REMOTE_ADDR"] || "-",
|
16
|
+
env["REMOTE_USER"] || "-",
|
17
|
+
now.strftime("%d/%b/%Y:%H:%M:%S %z"),
|
18
|
+
env['REQUEST_METHOD'],
|
19
|
+
env['PATH_INFO'],
|
20
|
+
env['QUERY_STRING'].empty? ? "" : "?"+env['QUERY_STRING'],
|
21
|
+
env["SERVER_PROTOCOL"],
|
22
|
+
status.to_s[0..3],
|
23
|
+
length,
|
24
|
+
now - began_at ]
|
25
|
+
|
26
|
+
@logger << msg
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Swee
|
2
|
+
|
3
|
+
class ContentLength
|
4
|
+
def initialize(app)
|
5
|
+
@app = app
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
status, headers, body = @app.call(env)
|
10
|
+
headers.merge!( { "Content-Length" => calc_length(body) } )
|
11
|
+
[status, headers, body]
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
def calc_length(body)
|
16
|
+
length = 0
|
17
|
+
body.each { |part| length += part.bytesize }
|
18
|
+
length
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Swee
|
2
|
+
|
3
|
+
class Reloader
|
4
|
+
def initialize(app,logger)
|
5
|
+
@app = app
|
6
|
+
@logger = logger
|
7
|
+
app_path = ENV["app_path"]
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
# 快速遍历 文件 mtime cache表
|
12
|
+
# mtime不一致则重新 load
|
13
|
+
Lodder.mtime_files.each_pair do |file,omtime|
|
14
|
+
mtime = File.mtime(file)
|
15
|
+
if mtime != omtime
|
16
|
+
load file
|
17
|
+
Lodder.mtime_files[file] = mtime
|
18
|
+
@logger << "#{file}文件已重载!"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
return @app.call(env)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/swee/routes.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
module Swee
|
2
|
+
class Routes
|
3
|
+
@@tables = {}
|
4
|
+
class RouteStruct
|
5
|
+
attr_reader :controller, :action, :request_methods
|
6
|
+
def initialize c,a,m
|
7
|
+
@controller,@action,@request_methods = c,a,m
|
8
|
+
end
|
9
|
+
|
10
|
+
def controller_name
|
11
|
+
"#{controller[0].upcase+controller[1..controller.size-1]}Controller"
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_controller_instance
|
15
|
+
eval "#{controller_name}.new"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
class << self
|
19
|
+
|
20
|
+
def get *args
|
21
|
+
self._parse "get",*args
|
22
|
+
end
|
23
|
+
|
24
|
+
def post *args
|
25
|
+
self._parse "post",*args
|
26
|
+
end
|
27
|
+
|
28
|
+
def match *args
|
29
|
+
self._parse "match",*args
|
30
|
+
end
|
31
|
+
|
32
|
+
def tables
|
33
|
+
@@tables
|
34
|
+
end
|
35
|
+
|
36
|
+
def _parse _m,*args
|
37
|
+
_path_info = args[0].to_s
|
38
|
+
if args[1] =~ /^(.*)#(.*)$/
|
39
|
+
@@tables[_path_info] = RouteStruct.new $1,$2, _m == "match" ? args[2][:via].map(&:to_sym) : [_m.to_sym]
|
40
|
+
else
|
41
|
+
raise "routes error!"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/swee/server.rb
ADDED
@@ -0,0 +1,298 @@
|
|
1
|
+
module Swee
|
2
|
+
class Server
|
3
|
+
include Daemonize
|
4
|
+
|
5
|
+
attr_reader :code_reload
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@config = Swee.config
|
9
|
+
@options = @config.server
|
10
|
+
|
11
|
+
@signature = nil
|
12
|
+
|
13
|
+
@handle_request_mode = @options[:handle_request_mode]
|
14
|
+
|
15
|
+
@restart_mode = @options[:restart_mode]
|
16
|
+
@pid_file = File.expand_path(@options[:pid_file],ENV["app_path"])
|
17
|
+
@touch_file = File.expand_path(@options[:touch_file],ENV["app_path"])
|
18
|
+
|
19
|
+
@logger = nil
|
20
|
+
@log_file_options = @options[:log_file]
|
21
|
+
@log_file = File.expand_path(@log_file_options.first,ENV["app_path"])
|
22
|
+
@log_file_options[0] = @log_file
|
23
|
+
|
24
|
+
@logger_level = @options[:logger_level]
|
25
|
+
|
26
|
+
@code_reload = @options[:code_reload]
|
27
|
+
|
28
|
+
# 最大连接数 和 稳定连接处
|
29
|
+
@maximum_connections = @options[:max_connections]
|
30
|
+
@maximum_persistent_connections = @options[:max_connections]
|
31
|
+
|
32
|
+
# 监听端口
|
33
|
+
@listen = @options[:listen]
|
34
|
+
|
35
|
+
# 实际连接 __id__ => connection
|
36
|
+
@connections = {}
|
37
|
+
|
38
|
+
# 超时时间
|
39
|
+
@timeout = 30
|
40
|
+
|
41
|
+
# 活动连接数
|
42
|
+
@persistent_connection_count = 0
|
43
|
+
|
44
|
+
# touch 模式重启时间
|
45
|
+
@restart_time = nil
|
46
|
+
|
47
|
+
# 信号队列 暂时只处理 :USR2
|
48
|
+
@signal_queue = []
|
49
|
+
|
50
|
+
# 守护进程
|
51
|
+
@daemonize = @options[:run_background]
|
52
|
+
|
53
|
+
# todo: 性能监控
|
54
|
+
# @performance_monitoring = @options[:performance_monitoring]
|
55
|
+
end
|
56
|
+
|
57
|
+
# 获取 Logger STDOUT 和 File
|
58
|
+
def logger
|
59
|
+
@logger
|
60
|
+
end
|
61
|
+
|
62
|
+
# 删除pid文件 用于重启 和 exit
|
63
|
+
def remove_pid_file
|
64
|
+
File.delete(@pid_file) if @pid_file && File.exists?(@pid_file)
|
65
|
+
end
|
66
|
+
|
67
|
+
# 读取pid文件 用于 USR2 信号获得后和Process.pid 比对
|
68
|
+
def read_pid_file
|
69
|
+
File.read(@pid_file)
|
70
|
+
end
|
71
|
+
|
72
|
+
# 写入Process.pid到 pid 文件
|
73
|
+
def write_pid_file
|
74
|
+
open(@pid_file,"w") { |f| f.write(Process.pid) }
|
75
|
+
File.chmod(0644, @pid_file)
|
76
|
+
end
|
77
|
+
|
78
|
+
# 是否运行标志
|
79
|
+
def running?
|
80
|
+
@running
|
81
|
+
end
|
82
|
+
|
83
|
+
# 强制停止
|
84
|
+
def stop!
|
85
|
+
@running = false
|
86
|
+
disconnect
|
87
|
+
EventMachine.stop
|
88
|
+
@connections.each_value { |connection| connection.close_connection }
|
89
|
+
end
|
90
|
+
|
91
|
+
# 放入 注册的 exit_at 函数中
|
92
|
+
# 重启 停止服务 -> 删除pid文件 -> 退出进程
|
93
|
+
#
|
94
|
+
def restart
|
95
|
+
stop!
|
96
|
+
remove_pid_file
|
97
|
+
exit
|
98
|
+
end
|
99
|
+
|
100
|
+
# 处理日志 stdout 和 file 两种
|
101
|
+
def handle_logger
|
102
|
+
# 创建日志文件
|
103
|
+
if !File.exist?(@log_file)
|
104
|
+
FileUtils.mkdir_p File.dirname(@log_file)
|
105
|
+
end
|
106
|
+
logs = []
|
107
|
+
logs << Logger.new(*@log_file_options)
|
108
|
+
unless @daemonize
|
109
|
+
logs << Logger.new(STDOUT)
|
110
|
+
end
|
111
|
+
|
112
|
+
# todo: 日志等级, datetime, 格式配置
|
113
|
+
# logs.each do |_logger|
|
114
|
+
# _logger.level = @logger_level
|
115
|
+
|
116
|
+
# _logger.datetime_format = '%Y-%m-%d %H:%M:%S'
|
117
|
+
# _logger.formatter = proc do |severity, datetime, progname, msg|
|
118
|
+
# "Started GET #{msg} at #{datetime}"
|
119
|
+
# end
|
120
|
+
# end
|
121
|
+
|
122
|
+
@logger = SweeLogger.new
|
123
|
+
|
124
|
+
logs.each { |_logger| @logger.addlog _logger }
|
125
|
+
end
|
126
|
+
|
127
|
+
# 处理重启
|
128
|
+
def handle_restart
|
129
|
+
send "handle_" + @restart_mode.to_s + "_restart"
|
130
|
+
end
|
131
|
+
|
132
|
+
# 处理touch重启方式
|
133
|
+
def handle_touch_restart
|
134
|
+
@restart_time = File.mtime(@touch_file)
|
135
|
+
end
|
136
|
+
|
137
|
+
# 处理pid重启方式
|
138
|
+
def handle_pid_restart
|
139
|
+
write_pid_file
|
140
|
+
end
|
141
|
+
|
142
|
+
# 判断是否为 touch 重启方式
|
143
|
+
def touch_mode?
|
144
|
+
@restart_mode == :touch
|
145
|
+
end
|
146
|
+
|
147
|
+
# 判断是否为 USR2 pid 重启方式
|
148
|
+
def pid_mode?
|
149
|
+
@restart_mode == :pid
|
150
|
+
end
|
151
|
+
|
152
|
+
# 判断 pid 文件是否为 当前进程ID
|
153
|
+
def current_pid? pid
|
154
|
+
read_pid_file == Process.pid.to_s
|
155
|
+
end
|
156
|
+
|
157
|
+
# 追踪重启 EM Timer 方式
|
158
|
+
# 每秒执行一次
|
159
|
+
# touch: 每秒读取touch文件 mtime
|
160
|
+
# pid: trap usr2 信号放入 信号队列, 然后每秒追踪队列变化获取信号
|
161
|
+
def trace_restart
|
162
|
+
if touch_mode?
|
163
|
+
EM.add_periodic_timer(1) {
|
164
|
+
mtime = File.mtime(@touch_file)
|
165
|
+
if mtime != @restart_time
|
166
|
+
@restart_time = mtime
|
167
|
+
puts "重启了"
|
168
|
+
restart
|
169
|
+
# 放弃 next_tick 原因:会在下次有请求时处理重启
|
170
|
+
# EM.next_tick { restart }
|
171
|
+
end
|
172
|
+
}
|
173
|
+
end
|
174
|
+
|
175
|
+
if pid_mode?
|
176
|
+
EM.add_periodic_timer(1) {
|
177
|
+
signal = @signal_queue.shift
|
178
|
+
case signal
|
179
|
+
when nil
|
180
|
+
when :QUIT # graceful shutdown
|
181
|
+
when :TERM, :INT # immediate shutdown
|
182
|
+
stop!
|
183
|
+
when :USR1 # rotate logs
|
184
|
+
when :USR2 # exec binary, stay alive in case something went wrong
|
185
|
+
_restart = current_pid?
|
186
|
+
when :WINCH
|
187
|
+
when :TTIN
|
188
|
+
when :TTOU
|
189
|
+
when :HUP
|
190
|
+
end
|
191
|
+
restart if _restart
|
192
|
+
}
|
193
|
+
trap(:USR2) {
|
194
|
+
# 收到 USR2信号加入 信号队列
|
195
|
+
@signal_queue << :USR2
|
196
|
+
}
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
# 处理守护进程(后台运行)
|
201
|
+
# 创建子进程
|
202
|
+
# 进程命名
|
203
|
+
# 注册守护进程重启
|
204
|
+
def handle_daemonize
|
205
|
+
# 先删除pid文件
|
206
|
+
remove_pid_file
|
207
|
+
|
208
|
+
# todo 关闭io 管道
|
209
|
+
# rd, wr = IO.pipe
|
210
|
+
# grandparent = $$
|
211
|
+
|
212
|
+
# 创建子进程
|
213
|
+
safefork && exit
|
214
|
+
|
215
|
+
# 设定进程名称
|
216
|
+
$0 = "swee"
|
217
|
+
|
218
|
+
# 重新创建pid文件
|
219
|
+
write_pid_file
|
220
|
+
|
221
|
+
# 注册守护进程重启
|
222
|
+
at_exit{
|
223
|
+
# 简单的用异常判断 系统退出,并非其他异常 获得重启
|
224
|
+
if $!.class == SystemExit
|
225
|
+
@logger << "Swee服务器重启!"
|
226
|
+
remove_pid_file
|
227
|
+
::Swee::Engine.restart_server!
|
228
|
+
end
|
229
|
+
}
|
230
|
+
end
|
231
|
+
|
232
|
+
# 创建日志 和 pid 文件
|
233
|
+
def create_touch_and_pid_file
|
234
|
+
[@pid_file,@touch_file].each do |_file|
|
235
|
+
if !File.exist?(_file)
|
236
|
+
FileUtils.mkdir_p File.dirname(_file)
|
237
|
+
open(_file,"w")
|
238
|
+
File.chmod(0644, _file)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
# 启动服务器
|
244
|
+
def run!
|
245
|
+
# 创建日志和pid文件
|
246
|
+
create_touch_and_pid_file
|
247
|
+
# 处理日志
|
248
|
+
handle_logger
|
249
|
+
# 处理重启
|
250
|
+
handle_restart
|
251
|
+
# EM默认配置
|
252
|
+
EventMachine.threadpool_size = 20
|
253
|
+
EventMachine.epoll
|
254
|
+
EventMachine.set_descriptor_table_size(@maximum_connections)
|
255
|
+
|
256
|
+
@logger << "正在启动swee服务器"
|
257
|
+
|
258
|
+
EventMachine::run {
|
259
|
+
@signature = connection
|
260
|
+
@running = true
|
261
|
+
|
262
|
+
# EM启动后处理后台守护进程运行
|
263
|
+
handle_daemonize if @daemonize
|
264
|
+
|
265
|
+
# 追踪重启文件
|
266
|
+
trace_restart
|
267
|
+
|
268
|
+
puts "swee 服务器已启动, 端口:#{@listen}"
|
269
|
+
}
|
270
|
+
end
|
271
|
+
|
272
|
+
# 连接
|
273
|
+
def connection
|
274
|
+
EventMachine::start_server "0.0.0.0", @listen, Connection do |_connection|
|
275
|
+
_connection.server = self
|
276
|
+
|
277
|
+
# 记录活动连接数
|
278
|
+
if @persistent_connection_count < @maximum_persistent_connections
|
279
|
+
@persistent_connection_count += 1
|
280
|
+
end
|
281
|
+
@connections[_connection.__id__] = _connection
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
# 断开
|
286
|
+
def disconnect
|
287
|
+
EventMachine.stop_server(@signature)
|
288
|
+
end
|
289
|
+
|
290
|
+
# 完成连接
|
291
|
+
def connection_finished(connection)
|
292
|
+
@persistent_connection_count -= 1
|
293
|
+
@connections.delete(connection.__id__)
|
294
|
+
|
295
|
+
# TODO: 停止或重启
|
296
|
+
end
|
297
|
+
end
|
298
|
+
end
|