rafaelgaspar-sexyprotocol 0.1.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,6 @@
1
+ module SexyProtocol
2
+ autoload :NetworkController, "sexyprotocol/network_controller"
3
+
4
+ autoload :Server, "sexyprotocol/server"
5
+ autoload :Client, "sexyprotocol/client"
6
+ end
@@ -0,0 +1,37 @@
1
+ module SexyProtocol
2
+ class Client
3
+ attr_reader :socket
4
+ attr_reader :network_controller
5
+
6
+ class << self; attr_accessor :network_controller_class; end
7
+ self.network_controller_class = SexyProtocol::NetworkController
8
+
9
+ def self.use_network_controller network_controller_class
10
+ self.network_controller_class = eval(network_controller_class.to_s)
11
+ end
12
+
13
+ def self.connect host, port, *args
14
+ new(host, port).connect(*args)
15
+ end
16
+
17
+ def initialize host, port
18
+ @host = host
19
+ @port = port
20
+ end
21
+
22
+ def connect *args
23
+ @socket = TCPSocket.open(@host, @port)
24
+ @network_controller = self.class.network_controller_class.new(@socket, *args).start
25
+
26
+ return self
27
+ end
28
+
29
+ def close
30
+ @network_controller.close
31
+ end
32
+
33
+ def closed?
34
+ @network_controller.closed?
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,53 @@
1
+ require "socket"
2
+
3
+ module SexyProtocol
4
+ class NetworkController
5
+ attr_reader :socket
6
+
7
+ def initialize socket
8
+ @socket = socket
9
+ end
10
+
11
+ def start
12
+ @thread = Thread.new do
13
+ connected if respond_to?(:connected)
14
+ if respond_to?(:received_data)
15
+ until @socket.closed?
16
+ new_data = receive_data
17
+ received_data(new_data) unless new_data.nil?
18
+ end
19
+ disconnected if respond_to?(:disconnected)
20
+ end
21
+ end
22
+
23
+ return self
24
+ end
25
+
26
+ def received_message message
27
+ puts message
28
+ end
29
+
30
+ def close
31
+ @thread.kill unless @thread.nil?
32
+ @socket.close unless @socket.closed?
33
+ disconnected if respond_to?(:disconnected)
34
+ end
35
+
36
+ def closed?
37
+ @socket.closed?
38
+ end
39
+
40
+ def send_data data
41
+ @socket.write([data.length].pack("I") + data)
42
+ end
43
+
44
+ def receive_data
45
+ length_raw_data = @socket.read(4)
46
+ if length_raw_data.nil?
47
+ return nil
48
+ else
49
+ return @socket.read(length_raw_data.unpack("I")[0])
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,54 @@
1
+ module SexyProtocol
2
+ class Server
3
+ attr_reader :socket
4
+ attr_reader :network_controllers
5
+
6
+ class << self; attr_accessor :network_controller_class; end
7
+ self.network_controller_class = SexyProtocol::NetworkController
8
+
9
+ def self.use_network_controller network_controller_class
10
+ self.network_controller_class = eval(network_controller_class.to_s)
11
+ end
12
+
13
+ def self.listen host, port, *args
14
+ new(host, port).listen(*args)
15
+ end
16
+
17
+ def initialize host, port
18
+ @host = host
19
+ @port = port
20
+ @network_controllers = []
21
+ end
22
+
23
+ def listen *args
24
+ @socket = TCPServer.open(@host, @port)
25
+
26
+ @thread = Thread.new do
27
+ while true
28
+ @network_controllers << self.class.network_controller_class.new(@socket.accept, *args).start
29
+ collect_garbaged_controllers
30
+ end
31
+ end
32
+
33
+ return self
34
+ end
35
+
36
+ def close
37
+ @thread.kill
38
+ @network_controllers.each do |controller|
39
+ controller.close
40
+ end
41
+ collect_garbaged_controllers
42
+ @socket.close
43
+ end
44
+
45
+ def closed?
46
+ @socket.closed?
47
+ end
48
+
49
+ private
50
+ def collect_garbaged_controllers
51
+ @network_controllers.delete_if { |controller| controller.closed? }
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,25 @@
1
+ dir = File.dirname(__FILE__)
2
+ lib_path = File.expand_path("#{dir}/../../lib")
3
+ $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
4
+ require "sexyprotocol"
5
+
6
+ describe SexyProtocol::Client do
7
+ before(:all) do
8
+ @server = TCPServer.open("0.0.0.0", 8000)
9
+ @client = SexyProtocol::Client.connect("localhost", 8000)
10
+ @server.accept
11
+ end
12
+
13
+ after(:all) do
14
+ @server.close
15
+ end
16
+
17
+ it "should be able to connect at a given host and port" do
18
+ @client.socket.should_not be_closed
19
+ end
20
+
21
+ it "should be able to disconnect" do
22
+ @client.close
23
+ @client.socket.should be_closed
24
+ end
25
+ end
@@ -0,0 +1,71 @@
1
+ dir = File.dirname(__FILE__)
2
+ lib_path = File.expand_path("#{dir}/../../lib")
3
+ $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
4
+ require "sexyprotocol"
5
+
6
+ describe SexyProtocol::NetworkController do
7
+ before(:all) do
8
+ @server = TCPServer.open("0.0.0.0", 8000)
9
+ @client = SexyProtocol::NetworkController.new(TCPSocket.open("localhost", 8000))
10
+ @session = @server.accept
11
+ end
12
+
13
+ after(:all) do
14
+ @server.close
15
+ end
16
+
17
+ it "should be able to get the socket" do
18
+ @client.socket.should be_instance_of(TCPSocket)
19
+ end
20
+
21
+ it "should be able to send a message" do
22
+ @client.send_data("Hello World!")
23
+ @session.read(16).should ==([12].pack("I") + "Hello World!")
24
+ end
25
+
26
+ it "should be able to receive a message" do
27
+ @session.write([12].pack("I") + "Hello World!")
28
+ @client.receive_data.should == "Hello World!"
29
+ end
30
+
31
+ end
32
+
33
+ describe SexyProtocol do
34
+ before do
35
+ @server = TCPServer.open("0.0.0.0", 8000)
36
+ @client = SexyProtocol::NetworkController.new(TCPSocket.open("localhost", 8000))
37
+ @session = @server.accept
38
+ end
39
+
40
+ after do
41
+ @server.close
42
+ end
43
+
44
+ it "should be sent connected message when it connects" do
45
+ @client.stub!(:connected)
46
+ @client.should_receive(:connected)
47
+
48
+ @client.start
49
+ sleep 0.01
50
+ end
51
+
52
+ it "should be sent received_message when message is received" do
53
+ @client.stub!(:received_data)
54
+ @client.should_receive(:received_data).with("Hello World!")
55
+ @session.write([12].pack("I") + "Hello World!")
56
+
57
+ @client.start
58
+ sleep 0.01
59
+ end
60
+
61
+ it "should be sent disconnected message when it disconnects" do
62
+ @client.stub!(:disconnected)
63
+ @client.should_receive(:disconnected)
64
+
65
+ @client.start
66
+ sleep 0.01
67
+
68
+ @client.close
69
+ sleep 0.01
70
+ end
71
+ end
@@ -0,0 +1,24 @@
1
+ dir = File.dirname(__FILE__)
2
+ lib_path = File.expand_path("#{dir}/../../lib")
3
+ $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
4
+ require "sexyprotocol"
5
+
6
+ describe SexyProtocol::Server do
7
+ it "should be able to receive connections at a given host and port" do
8
+ server = SexyProtocol::Server.listen("0.0.0.0", 8000)
9
+ client = TCPSocket.open("localhost", 8000)
10
+ sleep 0.1
11
+ server.network_controllers[0].should be_instance_of(SexyProtocol::NetworkController)
12
+ server.network_controllers[0].should_not be_closed
13
+
14
+ server.close
15
+ end
16
+ end
17
+
18
+ describe SexyProtocol do
19
+ it "should be able to get the socket" do
20
+ server = SexyProtocol::Server.listen("0.0.0.0", 8000)
21
+ server.socket.should be_instance_of(TCPServer)
22
+ server.close
23
+ end
24
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rafaelgaspar-sexyprotocol
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Rafael Gaspar
8
+ - Fernando Cezar
9
+ autorequire: sexyprotocol
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-05-16 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description:
18
+ email: rafael.gaspar@gmail.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - lib/sexyprotocol.rb
27
+ - lib/sexyprotocol
28
+ - lib/sexyprotocol/client.rb
29
+ - lib/sexyprotocol/server.rb
30
+ - lib/sexyprotocol/network_controller.rb
31
+ has_rdoc: false
32
+ homepage: http://www.github.com/rafaelgaspar/sexyprotocol
33
+ post_install_message:
34
+ rdoc_options: []
35
+
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: "0"
43
+ version:
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ requirements: []
51
+
52
+ rubyforge_project:
53
+ rubygems_version: 1.2.0
54
+ signing_key:
55
+ specification_version: 2
56
+ summary: An Event-Driven Network Framework for Rapid Network Client and Server Protocol Development.
57
+ test_files:
58
+ - spec/sexyprotocol/client_spec.rb
59
+ - spec/sexyprotocol/server_spec.rb
60
+ - spec/sexyprotocol/network_controller_spec.rb