93 lines
2.5 KiB
Ruby
93 lines
2.5 KiB
Ruby
|
|
# <<*>> -^v- SNOWARE APPLICATION
|
||
|
|
# usage: MINECRAFT Server monitoring.
|
||
|
|
# author: S.A.
|
||
|
|
# time: 2026-06-07
|
||
|
|
# license: All rights received.
|
||
|
|
|
||
|
|
# frozen_string_literal: true
|
||
|
|
|
||
|
|
module ServerStatusDetector
|
||
|
|
require 'socket'
|
||
|
|
require 'timeout'
|
||
|
|
|
||
|
|
class TcpServer
|
||
|
|
|
||
|
|
def self.test_port(host = '127.0.0.1', port = 25565, timeout = 10)
|
||
|
|
result = {
|
||
|
|
port: port,
|
||
|
|
status: :unknown,
|
||
|
|
response_time: nil
|
||
|
|
}
|
||
|
|
begin_time = Time.now
|
||
|
|
# 带错误处理的代码需要使用 begin...end
|
||
|
|
begin
|
||
|
|
Timeout.timeout(timeout) do # 此方法接收整数和代码块作为参数,并在超时时引发错误
|
||
|
|
socket = TCPSocket.new(host,port)
|
||
|
|
result[:status] = :open
|
||
|
|
result[:response_time] = (Time.now - begin_time).round(4)
|
||
|
|
socket.close
|
||
|
|
end
|
||
|
|
|
||
|
|
rescue Timeout::Error
|
||
|
|
result[:status] = :timeout
|
||
|
|
rescue Errno::ECONNREFUSED
|
||
|
|
result[:status] = :closed
|
||
|
|
rescue Errno::ECONNRESET
|
||
|
|
result[:status] = :interrupted
|
||
|
|
rescue Errno::ENETUNREACH, Errno::EHOSTUNREACH
|
||
|
|
result[:status] = :unreachable
|
||
|
|
rescue => error
|
||
|
|
result[:status] = :error
|
||
|
|
result[:error] = error.message
|
||
|
|
end
|
||
|
|
|
||
|
|
result
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
class MinecraftServer < TcpServer # 继承为TcpServer编写的属性和方法
|
||
|
|
|
||
|
|
def self.self_diag()
|
||
|
|
|
||
|
|
res = test_port('127.0.0.1', 25565)
|
||
|
|
|
||
|
|
if res[:error] != nil
|
||
|
|
message = "Unexpected ERROR when testing SMP by TCP: #{res[:status]},INFO: #{res[:error]}"
|
||
|
|
puts message
|
||
|
|
return {
|
||
|
|
type: false,
|
||
|
|
operation: ["Record"],
|
||
|
|
message: message,
|
||
|
|
}
|
||
|
|
end # 立刻错误处理是好习惯
|
||
|
|
|
||
|
|
case res[:status]
|
||
|
|
|
||
|
|
when :open
|
||
|
|
MethodExecutor.record("debug", "self_diag",
|
||
|
|
"TCP check OK — #{res[:response_time]}s")
|
||
|
|
return {
|
||
|
|
type: true,
|
||
|
|
}
|
||
|
|
when :timeout
|
||
|
|
MethodExecutor.record("warn", "self_diag",
|
||
|
|
"TCP check timed out.")
|
||
|
|
return {
|
||
|
|
type: false,
|
||
|
|
operation: ["Record"],
|
||
|
|
message: "We sent packet without response."
|
||
|
|
}
|
||
|
|
when :closed
|
||
|
|
MethodExecutor.record("warn", "self_diag",
|
||
|
|
"TCP port closed — server is down.")
|
||
|
|
return {
|
||
|
|
type: false,
|
||
|
|
operation: ["Record", "ForceResetServerProcess"], # 重启时注意要设置最大尝试次数
|
||
|
|
message: "Server died for unknown reason, and will be restarted."
|
||
|
|
}
|
||
|
|
end
|
||
|
|
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|