merona 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: