merona 1.0.0 → 1.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.
@@ -0,0 +1,25 @@
1
+ class Channel
2
+ def initialize
3
+ @clients = Array.new
4
+ end
5
+ def dispose
6
+ end
7
+
8
+ def subscribe(client)
9
+ @clients.push name
10
+ end
11
+ def unsubscribe(client)
12
+ @clients.delete name
13
+
14
+ if @clients.size == 0
15
+ return nil
16
+ else
17
+ return true
18
+ end
19
+ end
20
+ def publish(packet)
21
+ @clients.each do |client|
22
+ client.send packet
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,56 @@
1
+ class ChannelPool
2
+ def initialize
3
+ @channel = {}
4
+ end
5
+ def dispose
6
+ end
7
+
8
+ def tokenize(name, &block)
9
+ token = name.split(".")
10
+ if token.size > 1
11
+ ch = ""
12
+ for i in 0..token.size-2
13
+ ch += token[i] + "."
14
+ end
15
+ ch = ch[0..ch.length-2]
16
+
17
+ block.call ch
18
+ end
19
+ end
20
+
21
+ def subscribe(name, client)
22
+ tokenize(name) do |t|
23
+ subscribe t, client
24
+ end
25
+
26
+ if @channel[name] == nil
27
+ @channel[name] = Array.new
28
+ end
29
+
30
+ @channel[name].push client
31
+ end
32
+ def unsubscribe(name, client)
33
+ tokenize(name) do |t|
34
+ unsubscribe t, client
35
+ end
36
+
37
+ return if @channel[name] == nil
38
+
39
+ @channel[name].delete client
40
+
41
+ if @channel[name].size == 0
42
+ @channel[name] = nil
43
+ end
44
+ end
45
+ def publish(name, packet)
46
+ tokenize(name) do |t|
47
+ publish t, packet
48
+ end
49
+
50
+ return if @channel[name] == nil
51
+
52
+ @channel[name].each do |client|
53
+ client.send packet
54
+ end
55
+ end
56
+ end
data/lib/core/core.rb ADDED
@@ -0,0 +1,17 @@
1
+ def polling(&block)
2
+ EventMachine.run block
3
+ end
4
+
5
+ def meInitialize
6
+
7
+ Signal.trap("INT") do
8
+ Log.output "quit by user"
9
+ EventMachine.stop
10
+ end
11
+
12
+ t = Time.new
13
+ logfile = "log/#{t.year}.#{t.month}.#{t.day}.log"
14
+ Log.logfile = File.new(logfile, "a")
15
+
16
+ return true
17
+ end
@@ -0,0 +1,31 @@
1
+ class Version
2
+ attr_accessor :major, :minor, :fix
3
+
4
+ def initialize(major=1,minor=0,fix=0)
5
+ self.set(major,minor,fix)
6
+ end
7
+ def dispose
8
+ end
9
+
10
+ def set(major,minor,fix)
11
+ @major = major
12
+ @minof = minor
13
+ @fix = fix
14
+ end
15
+ end
16
+
17
+ def getMajorVersion
18
+ return 1
19
+ end
20
+ def getMinorVersion
21
+ return 0
22
+ end
23
+ def getFixVersion
24
+ return 0
25
+ end
26
+
27
+ def getVersion
28
+ ver = Version.new(
29
+ getMajorVersion,getMinorVersion,getFixVersion)
30
+ return ver
31
+ end
@@ -0,0 +1,35 @@
1
+ class Database
2
+ def initialize(addr="localhost", port=9999, id="public", pw="")
3
+ connect(addr, port , id, pw)
4
+ end
5
+ def dispose
6
+ disconnect
7
+ end
8
+
9
+ def connect(addr="localhost", port=9999, id="public", pw="")
10
+ end
11
+ def disconnect
12
+ end
13
+
14
+ def prepare(query)
15
+ end
16
+ def execute(query)
17
+ end
18
+
19
+ def select(table, row, condition="", option="")
20
+ stm = prepare("select #{row} from #{table} #{condition=="" ? "" : "where"} #{condition} #{option};")
21
+ stm.execute
22
+ end
23
+ def update(table, update, condition="", option="")
24
+ execute("update #{table} set #{update} #{condition=="" ? "" : "where"} #{condition} #{option};")
25
+ end
26
+ def insert(table, row, *args)
27
+ data = ""
28
+ args.each { |v| data += v.to_s + "," }
29
+ data = data[0..data.length-2]
30
+ execute("insert into #{table} (#{row}) values (#{data});")
31
+ end
32
+ def delete(table, condition, option="")
33
+ execute("delete from #{table} #{condition=="" ? "" : "where"} #{condition} #{option};")
34
+ end
35
+ end
data/lib/db/sqlite.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'sqlite3'
2
+
3
+ class SQLite < Database
4
+ def initialize(db)
5
+ connect db
6
+ end
7
+ def dispose
8
+ disconnect
9
+ end
10
+
11
+ def connect(addr)
12
+ @db = SQLite3::Database.new addr
13
+ end
14
+ def disconnect
15
+ @db.close
16
+ end
17
+
18
+ def prepare(query)
19
+ @db.prepare query
20
+ end
21
+ def execute(query)
22
+ @db.execute query
23
+ end
24
+ end
data/lib/debug/log.rb ADDED
@@ -0,0 +1,45 @@
1
+ def defLogger(msg)
2
+ puts msg
3
+ Log.logfile.puts msg
4
+ end
5
+
6
+ class Log
7
+ @@logfunc = method(:defLogger)
8
+ @@logfile
9
+
10
+ def initialize
11
+ end
12
+ def dispose
13
+ end
14
+
15
+ def self.logfile
16
+ @@logfile
17
+ end
18
+ def self.logfile=(fp)
19
+ @@logfile = fp
20
+ end
21
+
22
+ def self.logfunc
23
+ @@logfunc
24
+ end
25
+ def self.logfunc=(lf)
26
+ @@logfunc = lf
27
+ end
28
+
29
+ private
30
+ def self.time
31
+ t = Time.new
32
+ time = "[#{t.year}:#{t.month}:#{t.day}:#{t.hour}:#{t.min}:#{t.sec}]"
33
+ end
34
+
35
+ def self.warn(msg)
36
+ @@logfunc.call time + " [WARN] : " + msg
37
+ end
38
+ def self.error(msg)
39
+ @@logfunc.call time + " [ERROR] : " + msg
40
+ end
41
+ def self.output(msg)
42
+ @@logfunc.call time + " [LOG] : " + msg
43
+ end
44
+ end
45
+
@@ -0,0 +1,15 @@
1
+ class ChatHandler < Handler
2
+ def recv(server,connection,packet)
3
+ case packet.id
4
+ when Protocol::CHAT
5
+ puts "[#{packet["sender"]}] : #{packet["msg"]}"
6
+
7
+ reply = Packet.new
8
+ reply.id = Protocol::CHAT
9
+ reply["sender"] = packet["sender"]
10
+ reply["msg"] = packet["msg"]
11
+
12
+ server.pubsub.publish(packet.ch, reply)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ class Handler
2
+ def initialize
3
+ end
4
+ def dispose
5
+ end
6
+
7
+ def recv(server,connection,packet)
8
+ #case packet.id
9
+ # when Protocol::PacketID
10
+ # process code here
11
+ #end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class PubsubHandler
2
+ def recv(server,connection,packet)
3
+ case packet.id
4
+ when Protocol::SUBSCRIBE
5
+ server.pubsub.subscribe(packet.ch, connection)
6
+ puts "sub"
7
+ when Protocol::UNSUBSCRIBE
8
+ server.pubsub.unsubscribe(packet.ch, connection)
9
+ when Protocol::PUBLISH
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,33 @@
1
+ class SyncHandler < Handler
2
+ def recv(server,connection,packet)
3
+ case packet.id
4
+ when Protocol::SYNC
5
+ reply = Packet.new
6
+ reply.id = Protocol::SYNC
7
+ reply["x"] = packet["x"]
8
+ reply["y"] = packet["y"]
9
+ reply["oid"] = packet["oid"]
10
+
11
+ server.pubsub.publish(packet.ch, reply)
12
+ when Protocol::PUSH_OBJECT
13
+ reply = Packet.new
14
+ reply.id = Protocol::OBJECT_ID
15
+ reply["oid"] = $oid
16
+ $oid += 1
17
+
18
+ connection.send reply
19
+
20
+ reply.id = Protocol::PUSH_OBJECT
21
+ reply["x"] = packet["x"]
22
+ reply["y"] = packet["y"]
23
+
24
+ server.pubsub.publish(packet.ch, reply)
25
+ when Protocol::DELETE_OBJECT
26
+ reply = Packet.new
27
+ reply.id = Protocol::DELETE_OBJECT
28
+ reply["oid"] = packet["old"]
29
+
30
+ server.pubsub.publish(packet.ch, reply)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,25 @@
1
+ class UserHandler < Handler
2
+ def recv(server,connection,packet)
3
+ case packet.id
4
+ when Protocol::REGIST
5
+ when Protocol::UNREGIST
6
+ when Protocol::LOGIN
7
+ rs = connection.db.select("account", "*", "id=#{packet["id"]} and pw=#{paacket["pw"]}")
8
+ row = rs.next
9
+
10
+ reply = Packet.new
11
+ reply.id = LOGIN_RESULT
12
+ if row == nil
13
+ reply["result"] = nil
14
+ else
15
+ reply["result"] = true
16
+ connection.id = packet["id"]
17
+ connection.mem.push_prefix packet["id"]
18
+ end
19
+
20
+ rs.close
21
+ connection.send reply
22
+ when Protocol::LOGOUT
23
+ end
24
+ end
25
+ end
data/lib/merona.rb ADDED
@@ -0,0 +1,26 @@
1
+ # Merona
2
+
3
+ import 'core/*'
4
+ import 'debug/*'
5
+ import 'data/*'
6
+ import 'datastruct/*'
7
+
8
+ import 'channel/*'
9
+
10
+ import 'db/database.rb'
11
+ import 'db/*'
12
+
13
+ import 'sharedmem/shared_memory.rb'
14
+ import 'sharedmem/*'
15
+
16
+ import 'protocol/*'
17
+
18
+ import 'packet/packet.rb'
19
+ import 'packet/*'
20
+
21
+ import 'server/*'
22
+
23
+ import 'process/*'
24
+
25
+ import 'handler/handler.rb'
26
+ import 'handler/*'
@@ -0,0 +1,26 @@
1
+ class ChatPacket < Packet
2
+ def initialize
3
+ super
4
+ @id = Protocol::CHAT
5
+ end
6
+
7
+ def msg=(msg)
8
+ @data["msg"] = msg
9
+ end
10
+ def msg
11
+ @data["msg"]
12
+ end
13
+
14
+ def sender=(id)
15
+ @data["sender"] = id
16
+ end
17
+ def sender
18
+ @data["sender"]
19
+ end
20
+ def receiver(id)
21
+ @data["receiver"] = id
22
+ end
23
+ def receiver
24
+ @data["receiver"]
25
+ end
26
+ end
@@ -0,0 +1,51 @@
1
+ class Packet
2
+ attr_accessor :id
3
+ attr_accessor :size
4
+ attr_accessor :data
5
+ attr_accessor :ch
6
+
7
+ def initialize
8
+ @data = {}
9
+
10
+ @id = -1
11
+ @ch = "*"
12
+ end
13
+ def dispose
14
+ end
15
+
16
+ def push(name,data)
17
+ if name == nil
18
+ return
19
+ end
20
+
21
+ @data[name] = data
22
+ end
23
+ def get(name)
24
+ if name == nil
25
+ return
26
+ end
27
+
28
+ @data[name]
29
+ end
30
+
31
+ def []=(name,data)
32
+ push(name, data)
33
+ end
34
+ def [](name)
35
+ get(name)
36
+ end
37
+
38
+ def ch=(ch)
39
+ @ch = ch
40
+ end
41
+ def ch
42
+ @ch
43
+ end
44
+
45
+ def type=(type)
46
+ @data["type"] = type
47
+ end
48
+ def type
49
+ @data["type"]
50
+ end
51
+ end
@@ -0,0 +1,46 @@
1
+ class WorkItem
2
+ attr_accessor :packet
3
+ attr_accessor :sender
4
+
5
+ def initialize(sender, packet)
6
+ @packet = packet
7
+ @sender = sender
8
+ end
9
+ end
10
+
11
+ class ProcessPool
12
+ def initialize(server)
13
+ @server = server
14
+ @worker = Array.new
15
+
16
+ @queue = Queue.new
17
+ end
18
+ def dispose
19
+ end
20
+
21
+ def create_worker(n)
22
+ n.times do
23
+ thread = Thread.new do
24
+ while true
25
+ item = @queue.deq(false)
26
+
27
+ @server.handler.each do |handler|
28
+ handler.recv(@server, item.sender, item.packet)
29
+ end
30
+ end
31
+
32
+ @worker.push thread
33
+ end
34
+ end
35
+ end
36
+ def kill
37
+ @worker.each do |worker|
38
+ worker.kill
39
+ end
40
+ end
41
+
42
+ def enqueue(sender, item)
43
+ @queue.push WorkItem.new(sender, item)
44
+ end
45
+
46
+ end
@@ -0,0 +1,3 @@
1
+ class Protocol
2
+ CHAT = 1300
3
+ end
@@ -0,0 +1,5 @@
1
+ class Protocol
2
+ FIRST = 0
3
+
4
+ LAST = 99999
5
+ end
@@ -0,0 +1,7 @@
1
+ # 9000 ~ 9099
2
+ class Protocol
3
+ SUBSCRIBE = 9000
4
+ UNSUBSCRIBE = 9001
5
+
6
+ PUBLISH = 9010
7
+ end
@@ -0,0 +1,9 @@
1
+ # 1400 ~ 1499
2
+ class Protocol
3
+ SYNC = 1400
4
+
5
+ PUSH_OBJECT = 1410
6
+ OBJECT_ID = 1411
7
+
8
+ DELETE_OBJECT = 1420
9
+ end
@@ -0,0 +1,14 @@
1
+ # 1100 ~ 1199
2
+ class Protocol
3
+ REGIST = 1100
4
+ REGIST_RESULT = 1101
5
+
6
+ UNREGIST = 1110
7
+ UNREGIST_RESULT = 1111
8
+
9
+ LOGIN = 1120
10
+ LOGIN_RESULT = 1121
11
+
12
+ LOGOUT = 1130
13
+ LOGOUT_RESULT = 1131
14
+ end
@@ -0,0 +1,43 @@
1
+ require 'eventmachine'
2
+
3
+ class Connection < EM::Connection
4
+ include EM::P::ObjectProtocol
5
+
6
+ attr_accessor :id
7
+ attr_reader :ip, :port
8
+
9
+ def initialize(*args)
10
+ @port, @ip = Socket.unpack_sockaddr_in(get_peername)
11
+ @server = args[0]
12
+ @server.clients.push self
13
+
14
+ @db = DB.new DB_ACCOUNT
15
+ @mem = SHAREDMEM.new SHAREDMEM_HOST, SHAREDMEM_PORT
16
+
17
+ connect
18
+
19
+ set_sock_opt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, CONNECTION_NODELAY)
20
+ end
21
+ def unbind
22
+ @server.clients.delete self
23
+ @db.dispose
24
+ @mem.dispose
25
+
26
+ disconnect
27
+ end
28
+
29
+ def send(packet)
30
+ send_object packet
31
+ end
32
+ def receive_object(obj)
33
+ p obj
34
+ @server.process.enqueue(self, obj)
35
+ end
36
+
37
+ def connect
38
+ Log.output("new connection from " + @ip)
39
+ end
40
+ def disconnect
41
+ Log.output("lost connection " + @ip)
42
+ end
43
+ end
@@ -0,0 +1,49 @@
1
+ $server = {}
2
+
3
+ class Server
4
+ attr_reader :name
5
+ attr_reader :port
6
+ attr_reader :handler, :process
7
+ attr_reader :pubsub
8
+
9
+ attr_accessor :clients
10
+
11
+ def initialize(name,port,klass=Connection)
12
+ EventMachine.start_server("localhost", port, klass, self)
13
+
14
+ @clients = Array.new
15
+ @handler = Array.new
16
+
17
+ @pubsub = ChannelPool.new
18
+ @process = ProcessPool.new(self)
19
+ @process.create_worker SERVER_WORKERS
20
+
21
+ @name = name
22
+ @port = port
23
+
24
+ $server[@name] = self
25
+ end
26
+ def dispose
27
+ $server.delete @name
28
+ end
29
+
30
+ def add_handler(handler)
31
+ @handler.push handler.new
32
+ end
33
+ def delete_handler(handler)
34
+ @handler.each do |value|
35
+ if value.class == handler
36
+ @handler.delete value
37
+ end
38
+ end
39
+ end
40
+
41
+ def exclude(connection)
42
+ @clients.reject { |c| connection == c }
43
+ end
44
+ def broadcast(packet, exclusion = nil)
45
+ (exclusion ? exclude(exclusion) : @clients).each do |client|
46
+ client.send packet
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,16 @@
1
+ require 'redis'
2
+
3
+ class RedisMemory < SharedMemory
4
+ def initialize(host="localhost", port=6679)
5
+ @redis = Redis.new(:host => host, :port => port)
6
+ end
7
+ def dispose
8
+ end
9
+
10
+ def get(name)
11
+ @redis.get name
12
+ end
13
+ def set(name, value)
14
+ @redis.set name, value
15
+ end
16
+ end
@@ -0,0 +1,25 @@
1
+ class SharedMemory
2
+ attr_accessor :prefix
3
+
4
+ def initialize
5
+ @prefix = ""
6
+ end
7
+ def dispose
8
+ end
9
+
10
+ def push_prefix(prefix)
11
+ @prefix += prefix
12
+ end
13
+
14
+ def get(name)
15
+ end
16
+ def set(name, value)
17
+ end
18
+
19
+ def [](name)
20
+ get @prefix+name
21
+ end
22
+ def []=(name,value)
23
+ set @prefix+name, value
24
+ end
25
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: merona
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -65,10 +65,34 @@ email:
65
65
  executables: []
66
66
  extensions: []
67
67
  extra_rdoc_files: []
68
- files: []
68
+ files:
69
+ - lib/channel/channel.rb
70
+ - lib/channel/channel_pool.rb
71
+ - lib/core/core.rb
72
+ - lib/core/version.rb
73
+ - lib/db/database.rb
74
+ - lib/db/sqlite.rb
75
+ - lib/debug/log.rb
76
+ - lib/handler/chat_handler.rb
77
+ - lib/handler/handler.rb
78
+ - lib/handler/pubsub_handler.rb
79
+ - lib/handler/sync_handler.rb
80
+ - lib/handler/user_handler.rb
81
+ - lib/merona.rb
82
+ - lib/packet/chat_packet.rb
83
+ - lib/packet/packet.rb
84
+ - lib/process/process_pool.rb
85
+ - lib/protocol/chat_protocol.rb
86
+ - lib/protocol/protocol.rb
87
+ - lib/protocol/pubsub_protocol.rb
88
+ - lib/protocol/sync_protocol.rb
89
+ - lib/protocol/user_protocol.rb
90
+ - lib/server/connection.rb
91
+ - lib/server/server.rb
92
+ - lib/sharedmem/redis.rb
93
+ - lib/sharedmem/shared_memory.rb
69
94
  homepage: http://github.com/pjc0247/Merona
70
- licenses:
71
- - MIT
95
+ licenses: []
72
96
  post_install_message:
73
97
  rdoc_options: []
74
98
  require_paths: