rubame 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.
- data/lib/rubame.rb +177 -0
- metadata +45 -0
data/lib/rubame.rb
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'websocket'
|
2
|
+
require 'socket'
|
3
|
+
|
4
|
+
module Rubame
|
5
|
+
class Server
|
6
|
+
def initialize(host, port)
|
7
|
+
Socket.do_not_reverse_lookup
|
8
|
+
@hostname = host
|
9
|
+
@port = port
|
10
|
+
|
11
|
+
@reading = []
|
12
|
+
@writing = []
|
13
|
+
|
14
|
+
@clients = {} # Socket as key, and Client as value
|
15
|
+
|
16
|
+
@socket = TCPServer.new(@hostname, @port)
|
17
|
+
@reading.push @socket
|
18
|
+
end
|
19
|
+
|
20
|
+
def accept
|
21
|
+
socket = @socket.accept_nonblock
|
22
|
+
@reading.push socket
|
23
|
+
handshake = WebSocket::Handshake::Server.new
|
24
|
+
client = Rubame::Client.new(socket, handshake, self)
|
25
|
+
|
26
|
+
while line = socket.gets
|
27
|
+
client.handshake << line
|
28
|
+
break if client.handshake.finished?
|
29
|
+
end
|
30
|
+
if client.handshake.valid?
|
31
|
+
@clients[socket] = client
|
32
|
+
client.write handshake.to_s
|
33
|
+
client.opened = true
|
34
|
+
return client
|
35
|
+
else
|
36
|
+
close(client)
|
37
|
+
end
|
38
|
+
return nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def read(client)
|
42
|
+
|
43
|
+
pairs = client.socket.recvfrom(2000)
|
44
|
+
messages = []
|
45
|
+
|
46
|
+
if pairs[0].length == 0
|
47
|
+
close(client)
|
48
|
+
else
|
49
|
+
client.frame << pairs[0]
|
50
|
+
|
51
|
+
while f = client.frame.next
|
52
|
+
if (f.type == :close)
|
53
|
+
close(client)
|
54
|
+
return messages
|
55
|
+
else
|
56
|
+
messages.push f
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
return messages
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
def close(client)
|
67
|
+
puts "Closing socket"
|
68
|
+
@reading.delete client.socket
|
69
|
+
@clients.delete client.socket
|
70
|
+
begin
|
71
|
+
client.socket.close
|
72
|
+
rescue
|
73
|
+
end
|
74
|
+
client.closed = true
|
75
|
+
end
|
76
|
+
|
77
|
+
def run(&blk)
|
78
|
+
readable, writable = IO.select(@reading, @writing, nil, 0)
|
79
|
+
|
80
|
+
if readable
|
81
|
+
readable.each do |socket|
|
82
|
+
client = @clients[socket]
|
83
|
+
if socket == @socket
|
84
|
+
client = accept
|
85
|
+
else
|
86
|
+
msg = read(client)
|
87
|
+
client.messaged = msg
|
88
|
+
end
|
89
|
+
|
90
|
+
blk.call(client) if client and blk
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def stop
|
96
|
+
@socket.close
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
class Client
|
101
|
+
attr_accessor :socket, :handshake, :frame, :opened, :messaged, :closed
|
102
|
+
|
103
|
+
def initialize(socket, handshake, server)
|
104
|
+
@socket = socket
|
105
|
+
@handshake = handshake
|
106
|
+
@frame = WebSocket::Frame::Incoming::Server.new(:version => @handshake.version)
|
107
|
+
@opened = false
|
108
|
+
@messaged = []
|
109
|
+
@closed = false
|
110
|
+
@server = server
|
111
|
+
end
|
112
|
+
|
113
|
+
def write(data)
|
114
|
+
@socket.write data
|
115
|
+
end
|
116
|
+
|
117
|
+
def send(data)
|
118
|
+
frame = WebSocket::Frame::Outgoing::Server.new(:version => @handshake.version, :data => data, :type => :text)
|
119
|
+
begin
|
120
|
+
@socket.write frame
|
121
|
+
@socket.flush
|
122
|
+
rescue
|
123
|
+
@server.close(self) unless @closed
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def onopen(&blk)
|
128
|
+
if @opened
|
129
|
+
begin
|
130
|
+
blk.call
|
131
|
+
ensure
|
132
|
+
@opened = false
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def onmessage(&blk)
|
138
|
+
if @messaged.size > 0
|
139
|
+
begin
|
140
|
+
@messaged.each do |x|
|
141
|
+
blk.call(x.to_s)
|
142
|
+
end
|
143
|
+
ensure
|
144
|
+
@messaged = []
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def onclose(&blk)
|
150
|
+
if @closed
|
151
|
+
begin
|
152
|
+
blk.call
|
153
|
+
ensure
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
line = 0
|
160
|
+
end
|
161
|
+
|
162
|
+
if __FILE__==$0
|
163
|
+
server = Rubame::Server.new("0.0.0.0", 25222)
|
164
|
+
while (!$quit)
|
165
|
+
server.run do |client|
|
166
|
+
client.onopen do
|
167
|
+
puts "Server reports: client open"
|
168
|
+
end
|
169
|
+
client.onmessage do |mess|
|
170
|
+
puts "Server reports: message received: #{mess}"
|
171
|
+
end
|
172
|
+
client.onclose do
|
173
|
+
puts "Server reports: client closed"
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
metadata
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubame
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Mark Saward
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-06 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Ruby Websocket Game Server
|
15
|
+
email: me@marksaward.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/rubame.rb
|
21
|
+
homepage: http://github.com/saward/Rubame
|
22
|
+
licenses: []
|
23
|
+
post_install_message:
|
24
|
+
rdoc_options: []
|
25
|
+
require_paths:
|
26
|
+
- lib
|
27
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
requirements: []
|
40
|
+
rubyforge_project:
|
41
|
+
rubygems_version: 1.8.24
|
42
|
+
signing_key:
|
43
|
+
specification_version: 3
|
44
|
+
summary: Rubame
|
45
|
+
test_files: []
|