/
connection.rb
85 lines (73 loc) · 1.82 KB
/
connection.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
require 'net/rtmp/packet'
require 'net/rtmp/errors'
module Net
class RTMP
class Connection
HEADER_BYTE = "\x03"
HANDSHAKE_LENGTH = 1536
def initialize(socket)
@socket = WrappedSocket.new(socket)
@packets = {}
@headers = {}
end
def handshake
@socket.write("\x03" + random_string(HANDSHAKE_LENGTH))
shared = @socket.read(2 * HANDSHAKE_LENGTH + 1)[(HANDSHAKE_LENGTH + 1)..-1]
@socket.write(shared)
end
def get_data
header = Packet::Header.new
header.parse(@socket)
if packet = @packets[header.oid]
packet.endow(header)
else
if previous_header = @headers[header.oid]
header.inherit(previous_header)
end
packet = @packets[header.oid] = Packet.new(header)
end
@headers[header.oid] = header
packet << @socket.read(packet.bytes_to_fetch)
if packet.complete?
@packets.delete(header.oid)
yield packet
end
end
def need_data?
@packets.any?
end
def fetch(&blk)
get_data(&blk)
while need_data?
get_data(&blk)
end
end
def send(packet)
packet.generate do |chunk|
@socket.write(chunk)
end
end
private
def random_string(length)
(0...length).map{ rand(256) }.pack('C*')
end
class WrappedSocket
def initialize(socket)
@socket = socket
end
def read(length=nil)
if length
data = @socket.read(length)
raise NoMoreData if data.nil?
return data
else
return @socket.read
end
end
def write(data)
@socket.write(data)
end
end
end
end
end