Class: ZMachine::TCPChannel
Instance Attribute Summary collapse
Attributes inherited from Channel
#handler, #selector, #socket
Instance Method Summary
collapse
Constructor Details
#initialize(selector) ⇒ TCPChannel
Returns a new instance of TCPChannel.
10
11
12
13
14
|
# File 'lib/zmachine/tcp_channel.rb', line 10
def initialize(selector)
super(selector)
@close_scheduled = false
@connect_pending = false
end
|
Instance Attribute Details
#connect_pending ⇒ Object
Returns the value of attribute connect_pending.
8
9
10
|
# File 'lib/zmachine/tcp_channel.rb', line 8
def connect_pending
@connect_pending
end
|
Instance Method Details
#accept ⇒ Object
27
28
29
30
31
32
|
# File 'lib/zmachine/tcp_channel.rb', line 27
def accept
client_socket = socket.accept
return unless client_socket
client_socket.configure_blocking(false)
TCPChannel.new(client_socket, @selector)
end
|
#bind(address, port) ⇒ Object
20
21
22
23
24
25
|
# File 'lib/zmachine/tcp_channel.rb', line 20
def bind(address, port)
address = InetSocketAddress.new(address, port)
@socket = ServerSocketChannel.open
@socket.configure_blocking(false)
@socket.bind(address)
end
|
#close ⇒ Object
57
58
59
60
61
62
63
64
|
# File 'lib/zmachine/tcp_channel.rb', line 57
def close
if @channel_key
@channel_key.cancel
@channel_key = nil
end
@socket.close rescue nil
end
|
#connect(address, port) ⇒ Object
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
# File 'lib/zmachine/tcp_channel.rb', line 34
def connect(address, port)
address = InetSocketAddress.new(address, port)
@socket = SocketChannel.open
@socket.configure_blocking(false)
if socket.connect(address)
raise RuntimeError.new("immediate-connect unimplemented")
end
end
|
#current_events ⇒ Object
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
# File 'lib/zmachine/tcp_channel.rb', line 152
def current_events
if @socket.respond_to?(:accept)
return SelectionKey::OP_ACCEPT
end
events = 0
if @connect_pending
events |= SelectionKey::OP_CONNECT
else
events |= SelectionKey::OP_READ
events |= SelectionKey::OP_WRITE unless @outbound_queue.empty?
end
return events
end
|
#finish_connecting ⇒ Object
105
106
107
108
109
110
|
# File 'lib/zmachine/tcp_channel.rb', line 105
def finish_connecting
@socket.finish_connect
@connect_pending = false
update_events
return true
end
|
#has_more? ⇒ Boolean
148
149
150
|
# File 'lib/zmachine/tcp_channel.rb', line 148
def has_more?
false
end
|
#peer_name ⇒ Object
125
126
127
128
|
# File 'lib/zmachine/tcp_channel.rb', line 125
def peer_name
sock = @socket.socket
[sock.port, sock.inet_address.host_address]
end
|
#read_inbound_data(buffer) ⇒ Object
75
76
77
78
79
80
81
|
# File 'lib/zmachine/tcp_channel.rb', line 75
def read_inbound_data(buffer)
buffer.clear
raise IOException.new("eof") if @socket.read(buffer) == -1
buffer.flip
return if buffer.limit == 0
String.from_java_bytes(buffer.array[buffer.position...buffer.limit])
end
|
#register ⇒ Object
16
17
18
|
# File 'lib/zmachine/tcp_channel.rb', line 16
def register
@channel_key ||= @socket.register(@selector, current_events, self)
end
|
#schedule_close(after_writing) ⇒ Object
112
113
114
115
116
117
118
119
120
121
122
|
# File 'lib/zmachine/tcp_channel.rb', line 112
def schedule_close(after_writing)
@outbound_queue.clear unless after_writing
if @outbound_queue.empty?
return true
else
update_events
@close_scheduled = true
return false
end
end
|
#send_data(data) ⇒ Object
66
67
68
69
70
71
72
73
|
# File 'lib/zmachine/tcp_channel.rb', line 66
def send_data(data)
return if @close_scheduled
buffer = ByteBuffer.wrap(data.to_java_bytes)
if buffer.remaining() > 0
@outbound_queue << buffer
update_events
end
end
|
#sock_name ⇒ Object
130
131
132
133
|
# File 'lib/zmachine/tcp_channel.rb', line 130
def sock_name
sock = @socket.socket
[sock.local_port, sock.local_address.host_address]
end
|
#update_events ⇒ Object
140
141
142
143
144
145
146
|
# File 'lib/zmachine/tcp_channel.rb', line 140
def update_events
return unless @channel_key
events = current_events
if @channel_key.interest_ops != events
@channel_key.interest_ops(events)
end
end
|
#write_outbound_data ⇒ Object
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
# File 'lib/zmachine/tcp_channel.rb', line 83
def write_outbound_data
until @outbound_queue.empty?
buffer = @outbound_queue.first
@socket.write(buffer) if buffer.remaining > 0
if buffer.remaining == 0
@outbound_queue.shift
else
break
end
end
if @outbound_queue.empty? && !@close_scheduled
update_events
end
return (@close_scheduled && @outbound_queue.empty?) ? false : true
end
|