rubypitaya 1.1.0
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/bin/rubypitaya +56 -0
- data/lib/rubypitaya/app-template/Gemfile +10 -0
- data/lib/rubypitaya/app-template/Gemfile.lock +83 -0
- data/lib/rubypitaya/app-template/Makefile +91 -0
- data/lib/rubypitaya/app-template/Rakefile +57 -0
- data/lib/rubypitaya/app-template/app/app_initializer.rb +23 -0
- data/lib/rubypitaya/app-template/app/bll/player_bll.rb +10 -0
- data/lib/rubypitaya/app-template/app/config/initial_player.json +3 -0
- data/lib/rubypitaya/app-template/app/constants/status_codes.rb +15 -0
- data/lib/rubypitaya/app-template/app/handlers/hello_world_handler.rb +11 -0
- data/lib/rubypitaya/app-template/app/handlers/player_handler.rb +79 -0
- data/lib/rubypitaya/app-template/app/models/player.rb +15 -0
- data/lib/rubypitaya/app-template/app/models/user.rb +4 -0
- data/lib/rubypitaya/app-template/bin/console +22 -0
- data/lib/rubypitaya/app-template/config/database.yml +22 -0
- data/lib/rubypitaya/app-template/db/migrate/001_create_user_migration.rb +12 -0
- data/lib/rubypitaya/app-template/db/migrate/002_create_player_migration.rb +14 -0
- data/lib/rubypitaya/app-template/docker/dev/Dockerfile +19 -0
- data/lib/rubypitaya/app-template/docker/entrypoint.sh +13 -0
- data/lib/rubypitaya/app-template/docker/prod/Dockerfile +32 -0
- data/lib/rubypitaya/app-template/docker/prod/Makefile +67 -0
- data/lib/rubypitaya/app-template/docker-compose.yml +75 -0
- data/lib/rubypitaya/core/application_files_importer.rb +13 -0
- data/lib/rubypitaya/core/config.rb +33 -0
- data/lib/rubypitaya/core/database_config.rb +50 -0
- data/lib/rubypitaya/core/database_connector.rb +22 -0
- data/lib/rubypitaya/core/etcd_connector.rb +75 -0
- data/lib/rubypitaya/core/handler_base.rb +26 -0
- data/lib/rubypitaya/core/handler_router.rb +71 -0
- data/lib/rubypitaya/core/initializer_base.rb +8 -0
- data/lib/rubypitaya/core/initializer_broadcast.rb +15 -0
- data/lib/rubypitaya/core/initializer_content.rb +12 -0
- data/lib/rubypitaya/core/instance_holder.rb +17 -0
- data/lib/rubypitaya/core/main.rb +121 -0
- data/lib/rubypitaya/core/nats_connector.rb +148 -0
- data/lib/rubypitaya/core/parameters.rb +245 -0
- data/lib/rubypitaya/core/path.rb +13 -0
- data/lib/rubypitaya/core/postman.rb +31 -0
- data/lib/rubypitaya/core/redis_connector.rb +26 -0
- data/lib/rubypitaya/core/session.rb +29 -0
- data/lib/rubypitaya/version.rb +4 -0
- data/lib/rubypitaya.rb +20 -0
- metadata +240 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
version: '3'
|
2
|
+
services:
|
3
|
+
nats:
|
4
|
+
image: 'nats:2.1.4'
|
5
|
+
ports:
|
6
|
+
- '4222:4222'
|
7
|
+
|
8
|
+
etcd:
|
9
|
+
image: 'appcelerator/etcd:3.0.15'
|
10
|
+
ports:
|
11
|
+
- '2379:2379'
|
12
|
+
- '2380:2380'
|
13
|
+
|
14
|
+
redis:
|
15
|
+
image: 'redis:3.2.5-alpine'
|
16
|
+
ports:
|
17
|
+
- '9001:6379'
|
18
|
+
|
19
|
+
db:
|
20
|
+
image: 'postgres:9.6.17'
|
21
|
+
volumes:
|
22
|
+
- 'postgres:/var/lib/postgresql/data'
|
23
|
+
environment:
|
24
|
+
POSTGRES_USER: 'postgres'
|
25
|
+
POSTGRES_HOST_AUTH_METHOD: 'trust'
|
26
|
+
ports:
|
27
|
+
- '9100:5432'
|
28
|
+
|
29
|
+
connector:
|
30
|
+
image: 'registry.gitlab.com/lucianopc/pitaya-connector:0.1.0'
|
31
|
+
depends_on:
|
32
|
+
- 'db'
|
33
|
+
- 'nats'
|
34
|
+
- 'etcd'
|
35
|
+
- 'redis'
|
36
|
+
ports:
|
37
|
+
- '3252:3250'
|
38
|
+
environment:
|
39
|
+
PITAYA_CLUSTER_RPC_SERVER_NATS_CONNECT: 'nats://nats:4222'
|
40
|
+
PITAYA_CLUSTER_RPC_CLIENT_NATS_CONNECT: 'nats://nats:4222'
|
41
|
+
PITAYA_CLUSTER_RPC_CLIENT_NATS_REQUESTTIMEOUT: '10s'
|
42
|
+
PITAYA_CLUSTER_SD_ETCD_ENDPOINTS: 'etcd:2379'
|
43
|
+
PITAYA_CLUSTER_SD_ETCD_PREFIX: 'rubypitaya/'
|
44
|
+
SERVER_ROUTES: 'rubypitaya'
|
45
|
+
|
46
|
+
rubypitaya:
|
47
|
+
depends_on:
|
48
|
+
- 'db'
|
49
|
+
- 'nats'
|
50
|
+
- 'etcd'
|
51
|
+
- 'redis'
|
52
|
+
- 'connector'
|
53
|
+
build:
|
54
|
+
context: '.'
|
55
|
+
dockerfile: 'docker/dev/Dockerfile'
|
56
|
+
working_dir: '/app/rubypitaya'
|
57
|
+
volumes:
|
58
|
+
- '.:/app/rubypitaya'
|
59
|
+
- '/var/run/docker.sock:/var/run/docker.sock'
|
60
|
+
privileged: true
|
61
|
+
environment:
|
62
|
+
SERVER_NAME: 'rubypitaya'
|
63
|
+
RUBYPITAYA_ENV: 'development'
|
64
|
+
HISTFILE: '/app/rubypitaya/.bash-history'
|
65
|
+
NATS_URL: 'nats://nats:4222'
|
66
|
+
ETCD_URL: 'http://etcd:2379'
|
67
|
+
ETCD_PREFIX: 'rubypitaya/'
|
68
|
+
REDIS_URL: 'redis://redis:6379'
|
69
|
+
DATABASE_HOST: 'db'
|
70
|
+
DATABASE_USER: 'postgres'
|
71
|
+
DATABASE_PASSWORD: ''
|
72
|
+
DATABASE_NAME: 'ruby_pitaya'
|
73
|
+
|
74
|
+
volumes:
|
75
|
+
postgres:
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module RubyPitaya
|
2
|
+
|
3
|
+
class Config
|
4
|
+
|
5
|
+
def initialize(configs_folder_path)
|
6
|
+
path_to_all_files = File.join(configs_folder_path, '**/*.json')
|
7
|
+
config_files = Dir.glob(path_to_all_files)
|
8
|
+
|
9
|
+
config_hashes = []
|
10
|
+
|
11
|
+
config_files.each do |config_file|
|
12
|
+
config_text = File.open(config_file, &:read)
|
13
|
+
config_readed = JSON.parse(config_text)
|
14
|
+
|
15
|
+
path_array = config_file.sub(/^#{configs_folder_path}/, '')[0..-6]
|
16
|
+
.split('/')
|
17
|
+
config_hash = path_array.reverse.inject(config_readed) {|a, b| {b => a}}
|
18
|
+
|
19
|
+
config_hashes << config_hash
|
20
|
+
end
|
21
|
+
|
22
|
+
@config = config_hashes.inject(&:deep_merge)
|
23
|
+
end
|
24
|
+
|
25
|
+
def get
|
26
|
+
@config
|
27
|
+
end
|
28
|
+
|
29
|
+
def [](key)
|
30
|
+
@config[key]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
require 'rubypitaya/core/path'
|
5
|
+
|
6
|
+
module RubyPitaya
|
7
|
+
|
8
|
+
class DatabaseConfig
|
9
|
+
|
10
|
+
def initialize(environment_name, database_config_path)
|
11
|
+
@environment_name = environment_name
|
12
|
+
|
13
|
+
yaml_contents = File.open(database_config_path).read
|
14
|
+
@config = YAML.load( ERB.new(yaml_contents).result )
|
15
|
+
end
|
16
|
+
|
17
|
+
def config
|
18
|
+
@config[@environment_name]
|
19
|
+
end
|
20
|
+
|
21
|
+
def connection_data
|
22
|
+
{
|
23
|
+
'adapter': config['adapter'],
|
24
|
+
'encoding': config['encoding'],
|
25
|
+
'pool': config['pool'],
|
26
|
+
'host': config['host'],
|
27
|
+
'user': config['user'],
|
28
|
+
'database': config['database'],
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def connection_data_without_database
|
33
|
+
{
|
34
|
+
'adapter': config['adapter'],
|
35
|
+
'encoding': config['encoding'],
|
36
|
+
'pool': config['pool'],
|
37
|
+
'host': config['host'],
|
38
|
+
'user': config['user'],
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def database_name
|
43
|
+
config['database']
|
44
|
+
end
|
45
|
+
|
46
|
+
def migrations_path
|
47
|
+
@migrations_path
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'rubypitaya/core/database_config'
|
3
|
+
|
4
|
+
module RubyPitaya
|
5
|
+
|
6
|
+
class DatabaseConnector
|
7
|
+
|
8
|
+
def initialize(database_config)
|
9
|
+
@database_config = database_config
|
10
|
+
end
|
11
|
+
|
12
|
+
def connect
|
13
|
+
ActiveRecord::Base.establish_connection(@database_config.connection_data)
|
14
|
+
ActiveRecord::Base.logger = ActiveSupport::Logger.new(STDOUT)
|
15
|
+
ActiveSupport::LogSubscriber.colorize_logging = true
|
16
|
+
end
|
17
|
+
|
18
|
+
def disconnect
|
19
|
+
ActiveRecord::Base.connection.close
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'etcdv3'
|
3
|
+
|
4
|
+
module RubyPitaya
|
5
|
+
|
6
|
+
class EtcdConnector
|
7
|
+
|
8
|
+
def initialize(server_uuid, desktop_name, server_name, etcd_prefix,
|
9
|
+
etcd_address, allow_reconnect)
|
10
|
+
@server_uuid = server_uuid
|
11
|
+
@server_name = server_name
|
12
|
+
@desktop_name = desktop_name
|
13
|
+
@etcd_prefix = etcd_prefix
|
14
|
+
@etcd_address = etcd_address
|
15
|
+
@allow_reconnect = allow_reconnect
|
16
|
+
end
|
17
|
+
|
18
|
+
def connect
|
19
|
+
@connection = Etcdv3.new(endpoints: @etcd_address,
|
20
|
+
allow_reconnect: @allow_reconnect)
|
21
|
+
@connection.put(connection_key, connection_value)
|
22
|
+
end
|
23
|
+
|
24
|
+
def disconnect
|
25
|
+
@connection.del(connection_key)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def connection_key
|
31
|
+
"#{@etcd_prefix}servers/#{@server_name}/#{@server_uuid}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def connection_value
|
35
|
+
JSON.generate(get_server_data)
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_server_data
|
39
|
+
{
|
40
|
+
id: @server_uuid,
|
41
|
+
hostname: @desktop_name,
|
42
|
+
type: @server_name,
|
43
|
+
frontend: false,
|
44
|
+
metadata: {
|
45
|
+
stack: 'default',
|
46
|
+
stackInfo: JSON.generate({
|
47
|
+
Maintenance: false,
|
48
|
+
Platforms: {
|
49
|
+
android: {
|
50
|
+
Max: '9.9.9',
|
51
|
+
Min: '0.0.0'
|
52
|
+
},
|
53
|
+
ios: {
|
54
|
+
Max: '9.9.9',
|
55
|
+
Min: '0.0.0'
|
56
|
+
},
|
57
|
+
iphoneplayer: {
|
58
|
+
Max: '9.9.9',
|
59
|
+
Min: '0.0.0'
|
60
|
+
},
|
61
|
+
mac: {
|
62
|
+
Max: '9.9.9',
|
63
|
+
Min: '0.0.0'
|
64
|
+
},
|
65
|
+
osxeditor: {
|
66
|
+
Max: '9.9.9',
|
67
|
+
Min: '0.0.0'
|
68
|
+
}
|
69
|
+
}
|
70
|
+
})
|
71
|
+
}
|
72
|
+
}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module RubyPitaya
|
2
|
+
|
3
|
+
class HandlerBase
|
4
|
+
|
5
|
+
class_attribute :non_authenticated_routes, default: []
|
6
|
+
|
7
|
+
attr_accessor :bll, :redis, :config, :params, :session, :postman
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@bll = nil
|
11
|
+
@redis = nil
|
12
|
+
@config = nil
|
13
|
+
@params = nil
|
14
|
+
@session = nil
|
15
|
+
@postman = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.non_authenticated_actions(*action_names)
|
19
|
+
self.non_authenticated_routes = action_names.map(&:to_s)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.authenticated_action_name?(action_name)
|
23
|
+
!self.non_authenticated_routes.include?(action_name.to_s)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'rubypitaya/core/handler_base'
|
2
|
+
|
3
|
+
module RubyPitaya
|
4
|
+
|
5
|
+
class HandlerRouter
|
6
|
+
|
7
|
+
def initialize(handler_folder_path)
|
8
|
+
import_handler_files(handler_folder_path)
|
9
|
+
import_handler_classes
|
10
|
+
end
|
11
|
+
|
12
|
+
def import_handler_files(handler_folder_path)
|
13
|
+
Gem.find_files("#{handler_folder_path}/*.rb").each { |path| require path }
|
14
|
+
end
|
15
|
+
|
16
|
+
def import_handler_classes
|
17
|
+
handler_classes = ObjectSpace.each_object(HandlerBase.singleton_class).select do |klass|
|
18
|
+
klass != HandlerBase
|
19
|
+
end
|
20
|
+
|
21
|
+
@handlers = handler_classes.map { |handler_class| handler_class.new }
|
22
|
+
|
23
|
+
@handler_name_map = @handlers.map do |handler|
|
24
|
+
handler_name = handler.class.to_s
|
25
|
+
handler_name = handler_name[0].downcase + handler_name[1..-1]
|
26
|
+
|
27
|
+
[handler_name, handler]
|
28
|
+
end
|
29
|
+
@handler_name_map = @handler_name_map.to_h
|
30
|
+
end
|
31
|
+
|
32
|
+
def call(handler_name, action_name, session, postman, redis, config, bll,
|
33
|
+
params)
|
34
|
+
unless @handler_name_map.include?(handler_name)
|
35
|
+
return {
|
36
|
+
code: StatusCodes::CODE_HANDLER_NOT_FOUNDED,
|
37
|
+
msg: "Handler #{handler_name} not founded"
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
unless @handler_name_map[handler_name].methods.include?(action_name.to_sym)
|
42
|
+
return {
|
43
|
+
code: StatusCodes::CODE_ACTION_NOT_FOUNDED,
|
44
|
+
msg: "Handler #{handler_name} action #{action_name} not founded"
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
handler = @handler_name_map[handler_name]
|
49
|
+
|
50
|
+
handler.bll = bll
|
51
|
+
handler.redis = redis
|
52
|
+
handler.config = config
|
53
|
+
handler.params = params
|
54
|
+
handler.session = session
|
55
|
+
handler.postman = postman
|
56
|
+
|
57
|
+
if !handler.class.authenticated_action_name?(action_name)
|
58
|
+
handler.send(action_name)
|
59
|
+
else
|
60
|
+
if session.authenticated?
|
61
|
+
handler.send(action_name)
|
62
|
+
else
|
63
|
+
return {
|
64
|
+
code: StatusCodes::CODE_NOT_AUTHENTICATED,
|
65
|
+
msg: 'Not authenticated',
|
66
|
+
}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubypitaya/core/path'
|
2
|
+
require 'rubypitaya/core/initializer_base'
|
3
|
+
|
4
|
+
module RubyPitaya
|
5
|
+
|
6
|
+
class InitializerBroadcast
|
7
|
+
|
8
|
+
def run(initializer_content)
|
9
|
+
ObjectSpace.each_object(InitializerBase.singleton_class) do |klass|
|
10
|
+
instance = klass.new
|
11
|
+
instance.run(initializer_content)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require 'securerandom'
|
3
|
+
require 'active_model'
|
4
|
+
|
5
|
+
require 'rubypitaya/core/path'
|
6
|
+
require 'rubypitaya/core/config'
|
7
|
+
require 'rubypitaya/core/session'
|
8
|
+
require 'rubypitaya/core/postman'
|
9
|
+
require 'rubypitaya/core/parameters'
|
10
|
+
require 'rubypitaya/core/handler_router'
|
11
|
+
require 'rubypitaya/core/etcd_connector'
|
12
|
+
require 'rubypitaya/core/nats_connector'
|
13
|
+
require 'rubypitaya/core/database_config'
|
14
|
+
require 'rubypitaya/core/redis_connector'
|
15
|
+
require 'rubypitaya/core/instance_holder'
|
16
|
+
require 'rubypitaya/core/database_connector'
|
17
|
+
require 'rubypitaya/core/initializer_content'
|
18
|
+
require 'rubypitaya/core/initializer_broadcast'
|
19
|
+
require 'rubypitaya/core/application_files_importer'
|
20
|
+
|
21
|
+
module RubyPitaya
|
22
|
+
|
23
|
+
class Main
|
24
|
+
|
25
|
+
attr_reader :redis_connector, :config, :bll
|
26
|
+
|
27
|
+
private
|
28
|
+
def initialize
|
29
|
+
@application_files_importer = ApplicationFilesImporter.new
|
30
|
+
@application_files_importer.import
|
31
|
+
|
32
|
+
@server_name = ENV['SERVER_NAME']
|
33
|
+
@service_uuid = SecureRandom.uuid
|
34
|
+
@desktop_name = Socket.gethostname
|
35
|
+
|
36
|
+
@etcd_prefix = ENV['ETCD_PREFIX']
|
37
|
+
@etcd_address = ENV['ETCD_URL']
|
38
|
+
@allow_reconnect = false
|
39
|
+
@etcd_connector = EtcdConnector.new(@service_uuid, @desktop_name,
|
40
|
+
@server_name, @etcd_prefix,
|
41
|
+
@etcd_address, @allow_reconnect)
|
42
|
+
@etcd_connector.connect
|
43
|
+
|
44
|
+
@nats_address = ENV['NATS_URL']
|
45
|
+
@nats_connector = NatsConnector.new(@nats_address, @service_uuid,
|
46
|
+
@server_name)
|
47
|
+
|
48
|
+
@redis_address = ENV['REDIS_URL']
|
49
|
+
@redis_connector = RedisConnector.new(@redis_address)
|
50
|
+
@redis_connector.connect
|
51
|
+
|
52
|
+
@environment_name = ENV.fetch("RUBYPITAYA_ENV") { 'development' }
|
53
|
+
@database_config = DatabaseConfig.new(@environment_name, Path::DATABASE_CONFIG_PATH)
|
54
|
+
@database_connector = DatabaseConnector.new(@database_config)
|
55
|
+
@database_connector.connect
|
56
|
+
|
57
|
+
@session = Session.new
|
58
|
+
@postman = Postman.new(@nats_connector)
|
59
|
+
@config = Config.new(Path::APP_CONFIG_FOLDER_PATH)
|
60
|
+
|
61
|
+
@bll = InstanceHolder.new
|
62
|
+
|
63
|
+
@initializer_content = InitializerContent.new(@bll, @redis_connector.redis)
|
64
|
+
@initializer_broadcast = InitializerBroadcast.new
|
65
|
+
@initializer_broadcast.run(@initializer_content)
|
66
|
+
|
67
|
+
@handler_router = HandlerRouter.new(Path::HANDLERS_FOLDER_PATH)
|
68
|
+
|
69
|
+
puts "Server started!"
|
70
|
+
run_nats_connection
|
71
|
+
|
72
|
+
@etcd_connector.disconnect
|
73
|
+
@database_connector.disconnect
|
74
|
+
end
|
75
|
+
|
76
|
+
def run_nats_connection
|
77
|
+
@nats_connector.connect do |request|
|
78
|
+
start_time_seconds = Time.now.to_i
|
79
|
+
|
80
|
+
message_route = request[:msg][:route]
|
81
|
+
message_data = request[:msg][:data]
|
82
|
+
message_data = JSON.parse(message_data) if message_data.class == String
|
83
|
+
|
84
|
+
params = Parameters.new(message_data)
|
85
|
+
|
86
|
+
session_id = request[:session][:id]
|
87
|
+
session_uid = request[:session].fetch(:uid, '')
|
88
|
+
session_data = request[:session][:data]
|
89
|
+
session_data = JSON.parse(session_data) if session_data.class == String
|
90
|
+
frontend_id = request[:frontendID]
|
91
|
+
metadata = request[:metadata]
|
92
|
+
metadata = JSON.parse(metadata) if metadata.class == String
|
93
|
+
|
94
|
+
@session.update(session_id, session_uid, session_data, metadata,
|
95
|
+
frontend_id)
|
96
|
+
|
97
|
+
handler_name, action_name = message_route.split('.')[1..-1]
|
98
|
+
|
99
|
+
puts "request -> route: #{message_route}"
|
100
|
+
puts " -> data: #{message_data}"
|
101
|
+
|
102
|
+
response = @handler_router.call(handler_name, action_name, @session,
|
103
|
+
@postman, @redis_connector.redis,
|
104
|
+
@config, @bll, params)
|
105
|
+
|
106
|
+
delta_time_seconds = Time.now.to_i - start_time_seconds
|
107
|
+
|
108
|
+
puts "response [#{delta_time_seconds}s] -> #{response.to_json}"
|
109
|
+
|
110
|
+
response
|
111
|
+
end
|
112
|
+
rescue SystemExit, Interrupt
|
113
|
+
puts "Quit!"
|
114
|
+
return 0
|
115
|
+
rescue Exception => error
|
116
|
+
puts "ERROR: #{error}"
|
117
|
+
puts error.backtrace
|
118
|
+
run_nats_connection
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require 'protobuf'
|
2
|
+
require 'nats/client'
|
3
|
+
|
4
|
+
module RubyPitaya
|
5
|
+
|
6
|
+
class NatsConnector
|
7
|
+
|
8
|
+
REQUEST_TYPE_SYS = 0
|
9
|
+
REQUEST_TYPE_USER = 1
|
10
|
+
|
11
|
+
MESSAGE_TYPE_REQUEST = 0
|
12
|
+
MESSAGE_TYPE_NOTIFY = 1
|
13
|
+
MESSAGE_TYPE_RESPONSE = 2
|
14
|
+
MESSAGE_TYPE_PUSH = 3
|
15
|
+
|
16
|
+
def initialize(nats_address, server_uuid, server_name)
|
17
|
+
@server_uuid = server_uuid
|
18
|
+
@server_name = server_name
|
19
|
+
@nats_address = nats_address
|
20
|
+
end
|
21
|
+
|
22
|
+
def connect
|
23
|
+
NATS.start(:servers => [@nats_address]) do |nc|
|
24
|
+
|
25
|
+
NATS.subscribe(subscribe_topic) do |message, reply, a, b|
|
26
|
+
request = NatsRequest.decode(message).to_hash
|
27
|
+
|
28
|
+
Fiber.new do
|
29
|
+
response = yield request
|
30
|
+
|
31
|
+
nats_response = NatsResponse.new(data: response.to_json)
|
32
|
+
|
33
|
+
NATS.publish(reply, nats_response)
|
34
|
+
end.resume
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def push_to_frontend(session, message_route, payload)
|
41
|
+
frontend_topic = get_frontend_topic(session.frontend_id)
|
42
|
+
|
43
|
+
nats_message = NatsMessage.new(
|
44
|
+
route: message_route,
|
45
|
+
data: payload,
|
46
|
+
reply: @server_uuid,
|
47
|
+
type: MESSAGE_TYPE_REQUEST,
|
48
|
+
)
|
49
|
+
|
50
|
+
nats_session = NatsSession.new(
|
51
|
+
id: session.id,
|
52
|
+
uid: session.uid,
|
53
|
+
data: session.data.to_json,
|
54
|
+
)
|
55
|
+
|
56
|
+
nats_request = NatsRequest.new(
|
57
|
+
type: REQUEST_TYPE_USER,
|
58
|
+
session: nats_session,
|
59
|
+
msg: nats_message,
|
60
|
+
frontendID: session.frontend_id,
|
61
|
+
metadata: session.metadata.to_json,
|
62
|
+
)
|
63
|
+
|
64
|
+
nats_response = NATS.request(frontend_topic, nats_request)
|
65
|
+
response = NatsResponse.decode(nats_response).to_hash
|
66
|
+
|
67
|
+
response
|
68
|
+
end
|
69
|
+
|
70
|
+
def push_to_user(uid, message_route, payload)
|
71
|
+
user_topic = get_user_message_topic(uid)
|
72
|
+
|
73
|
+
nats_push = NatsPush.new(
|
74
|
+
route: message_route,
|
75
|
+
uid: uid,
|
76
|
+
data: payload.to_json,
|
77
|
+
)
|
78
|
+
|
79
|
+
NATS.publish(user_topic, nats_push)
|
80
|
+
|
81
|
+
0
|
82
|
+
end
|
83
|
+
|
84
|
+
def subscribe_topic
|
85
|
+
"pitaya/servers/#{@server_name}/#{@server_uuid}"
|
86
|
+
end
|
87
|
+
|
88
|
+
def get_frontend_topic(frontend_id)
|
89
|
+
"pitaya/servers/connector/#{frontend_id}"
|
90
|
+
end
|
91
|
+
|
92
|
+
def get_user_message_topic(uid)
|
93
|
+
"pitaya/connector/user/#{uid}/push"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
class NatsSession < ::Protobuf::Message; end
|
98
|
+
class NatsMessage < ::Protobuf::Message; end
|
99
|
+
class NatsRequest < ::Protobuf::Message; end
|
100
|
+
class NatsResponse < ::Protobuf::Message; end
|
101
|
+
class NatsError < ::Protobuf::Message; end
|
102
|
+
class NatsBindMsg < ::Protobuf::Message; end
|
103
|
+
class NatsPush < ::Protobuf::Message; end
|
104
|
+
|
105
|
+
class NatsSession
|
106
|
+
optional :int32, :id, 1
|
107
|
+
optional :bytes, :uid, 2
|
108
|
+
optional :bytes, :data, 3
|
109
|
+
end
|
110
|
+
|
111
|
+
class NatsMessage
|
112
|
+
optional :int32, :id, 1
|
113
|
+
optional :bytes, :route, 2
|
114
|
+
optional :bytes, :data, 3
|
115
|
+
optional :bytes, :reply, 4
|
116
|
+
optional :int32, :type, 5
|
117
|
+
end
|
118
|
+
|
119
|
+
class NatsRequest
|
120
|
+
optional :int32, :type, 1
|
121
|
+
optional NatsSession, :session, 2
|
122
|
+
optional NatsMessage, :msg, 3
|
123
|
+
optional :bytes, :frontendID, 4
|
124
|
+
optional :bytes, :metadata, 5
|
125
|
+
end
|
126
|
+
|
127
|
+
class NatsError
|
128
|
+
optional :bytes, :code, 1
|
129
|
+
optional :bytes, :message, 2
|
130
|
+
optional :bytes, :metadata, 3
|
131
|
+
end
|
132
|
+
|
133
|
+
class NatsResponse
|
134
|
+
optional :bytes, :data, 1
|
135
|
+
optional NatsError, :error, 2
|
136
|
+
end
|
137
|
+
|
138
|
+
class NatsBindMsg
|
139
|
+
optional :bytes, :uid, 1
|
140
|
+
optional :bytes, :fid, 2
|
141
|
+
end
|
142
|
+
|
143
|
+
class NatsPush
|
144
|
+
optional :bytes, :route, 1
|
145
|
+
optional :bytes, :uid, 2
|
146
|
+
optional :bytes, :data, 3
|
147
|
+
end
|
148
|
+
end
|