hara 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -3,13 +3,13 @@
3
3
  [![Gem Version](https://badge.fury.io/rb/hara.png)](http://badge.fury.io/rb/hara)
4
4
  [![Build Status](https://travis-ci.org/jjyr/hara.png?branch=master)](https://travis-ci.org/jjyr/hara)
5
5
 
6
- Hara is a simple framework, help you build async & concurrent websocket server.
6
+ Hara is a simple framework, help you build async-io & concurrent websocket server.
7
7
 
8
- Hara's async ability from [em-websocket](https://github.com/igrigorik/em-websocket),
8
+ Hara's async-io ability from [em-websocket](https://github.com/igrigorik/em-websocket),
9
9
 
10
10
  Hara's concurrent ability from [celluloid](https://github.com/celluloid/celluloid).
11
11
 
12
- Yes, hara is a combination of them, eventmachine and celluloid work well together :)
12
+ Seems eventmachine and celluloid work well together :smile:
13
13
 
14
14
  ## Installation
15
15
 
@@ -57,13 +57,14 @@ ws.send(msg)
57
57
 
58
58
  `ruby test.rb -h` to view options
59
59
 
60
- ## Other Usages & How it work
60
+ ## Full Usages
61
61
 
62
62
  ```ruby
63
63
  require 'hara/base'
64
64
 
65
65
  class Echo
66
- #include Hara::App, make you Echo class become Celluloid::Actor and per actor handle a socket
66
+ #include Hara::App, make you Echo class become Celluloid::Actor,
67
+ # and per actor handle a socket
67
68
  include Hara::App
68
69
 
69
70
  #Hara::App provide some callbacks
@@ -79,22 +80,40 @@ class Echo
79
80
 
80
81
  define_action :echo do |str|
81
82
  puts "#{client_ip} #{client_port}"
83
+ #send message to socket
82
84
  socket.send str
83
85
  end
84
86
 
87
+ define_action :exit do
88
+ puts "#{client_ip} exit"
89
+ # close client connection
90
+ close
91
+ end
92
+
85
93
  def after_action action, *args
86
94
  puts 'called when action complete'
87
95
  end
96
+
97
+ def action_missing action, *args
98
+ socket.send 'error'
99
+ super
100
+ end
101
+
102
+ def on_close close_info
103
+ puts "#{client_ip} connection closed"
104
+ end
88
105
  end
89
106
 
90
107
  #if you require 'hara/base' you need start server you self, like below
91
108
  Hara::Server.start 'localhost', '3000'
92
109
  ```
93
110
 
94
- ## RoadMap
111
+ ## Client
95
112
 
96
113
  js client is processing
97
114
 
115
+ current format is JSON.stringify({action: 'echo',args:['hello world']})
116
+
98
117
  ## Contributing
99
118
 
100
119
  1. Fork it
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.version = Hara::VERSION
9
9
  spec.authors = ["jjy"]
10
10
  spec.email = ["jjyruby@gmail.com"]
11
- spec.description = %q{Hara help you build async & concurrent websocket server.}
11
+ spec.description = %q{Hara help you build async-io & concurrent websocket server.}
12
12
  spec.summary = %q{In fact, hara just a combination of em-websocket and celluloid, but it really help you write applications easily.}
13
13
  spec.homepage = "http://github.com/jjyr/hara"
14
14
  spec.license = "MIT"
@@ -61,7 +61,7 @@ module Hara
61
61
  def after_action action, args
62
62
  end
63
63
 
64
- def on_close
64
+ def on_close close_info = {}
65
65
  end
66
66
 
67
67
  ##################
@@ -77,6 +77,11 @@ module Hara
77
77
  handshake.headers_downcased
78
78
  end
79
79
 
80
+ # close connection
81
+ def close code = nil, body = nil
82
+ @socket.close code, body
83
+ end
84
+
80
85
  #below are internal functions(should not been overriding)
81
86
 
82
87
  def initialize handshake, socket
@@ -110,8 +115,12 @@ module Hara
110
115
  end
111
116
  end
112
117
 
118
+ def set_close_info close_info
119
+ @_close_info = close_info
120
+ end
121
+
113
122
  def app_finalizer
114
- on_close
123
+ on_close @_close_info
115
124
  ensure
116
125
  @socket.close if @socket
117
126
  end
@@ -16,8 +16,9 @@ module Hara
16
16
  actor = Hara::Application.new handshake, ws
17
17
  }
18
18
 
19
- ws.onclose {
19
+ ws.onclose {|close_info = {}|
20
20
  begin
21
+ actor.async.set_close_info close_info
21
22
  actor.terminate! if actor.alive?
22
23
  rescue Celluloid::DeadActorError => e
23
24
  end
@@ -1,3 +1,3 @@
1
1
  module Hara
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
@@ -17,7 +17,7 @@ describe Hara::App do
17
17
  @states << [:after_action, action, args]
18
18
  end
19
19
 
20
- def on_close
20
+ def on_close close_info
21
21
  @states << :closed
22
22
  end
23
23
 
@@ -29,6 +29,10 @@ describe Hara::App do
29
29
  socket.send "hello#{msg}"
30
30
  end
31
31
 
32
+ define_action :exit do
33
+ close 3333, "Bye"
34
+ end
35
+
32
36
  def states
33
37
  @states
34
38
  end
@@ -39,6 +43,7 @@ describe Hara::App do
39
43
  @handshake = FayeHandshake.new
40
44
  @socket = FayeSocket.new
41
45
  @app = Hara::Application.new @handshake, @socket
46
+ @socket.app = @app
42
47
  end
43
48
 
44
49
  after :each do
@@ -55,20 +60,29 @@ describe Hara::App do
55
60
 
56
61
  it 'remote call actions' do
57
62
  @app.process_msg(Hara.encode_msg(:hello, ' world'))
58
- sleep 0.1 until msg = @socket.client_read
63
+ msg = nil
64
+ wait_until{msg = @socket.client_read}
59
65
  msg.should == 'hello world'
60
66
  end
61
67
 
68
+ it 'close should close connection' do
69
+ @app.process_msg(Hara.encode_msg(:exit))
70
+ wait_until{!@app.alive?}
71
+ @socket.alive?.should == false
72
+ @socket.close_info.should == [3333, 'Bye']
73
+ end
74
+
62
75
  it 'error remote call' do
63
76
  @app.process_msg('a error call')
64
- sleep 0.1 while @app.alive?
77
+ wait_until{!@app.alive?}
65
78
  msg = @socket.client_read
66
79
  msg.should == nil
67
80
  end
68
81
 
69
82
  it 'action_missing should work' do
70
83
  @app.process_msg(Hara.encode_msg(:hello_world, 'hello', 'world'))
71
- sleep 0.1 until msg = @socket.client_read
84
+ msg = nil
85
+ wait_until{msg = @socket.client_read}
72
86
  msg.should == [:action_missing, 'hello_world', ['hello', 'world']]
73
87
  end
74
88
 
@@ -77,7 +91,7 @@ describe Hara::App do
77
91
  states = @app.states
78
92
  sleep 0.2
79
93
  @app.terminate
80
- sleep 0.1 while @app.alive?
94
+ wait_until{!@app.alive?}
81
95
  action_callbacks = [[:before_action, "hello", [" world"]], [:after_action, "hello", [" world"]]]
82
96
  states.should == [*(action_callbacks * 2),:closed]
83
97
  end
@@ -2,6 +2,12 @@ require 'hara/base'
2
2
 
3
3
  Celluloid.logger = nil
4
4
 
5
+ def wait_until wait_time = 3
6
+ timeout wait_time do
7
+ sleep 0.1 until yield
8
+ end
9
+ end
10
+
5
11
  class FayeHandshake
6
12
  def headers_downcased
7
13
  {'host' => 'localhost:8080'}
@@ -9,7 +15,7 @@ class FayeHandshake
9
15
  end
10
16
 
11
17
  class FayeSocket
12
- attr_accessor :remote_ip
18
+ attr_accessor :remote_ip, :close_info, :app
13
19
 
14
20
  def initialize
15
21
  @client_messages = []
@@ -18,6 +24,11 @@ class FayeSocket
18
24
  @jruby_peername = "\x00\x02\x8Av\x7F\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
19
25
  end
20
26
 
27
+ def app= app
28
+ @app = app
29
+ @alive = true
30
+ end
31
+
21
32
  def get_peername
22
33
  defined?(JRuby) ? @jruby_peername : @mri_peername
23
34
  end
@@ -26,8 +37,12 @@ class FayeSocket
26
37
  @alive
27
38
  end
28
39
 
29
- def close
30
- @alive = false
40
+ def close code = nil, body = nil
41
+ if @alive
42
+ @close_info = [code, body]
43
+ @alive = false
44
+ @app.terminate!
45
+ end
31
46
  end
32
47
 
33
48
  def send message
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hara
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-16 00:00:00.000000000 Z
12
+ date: 2013-07-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: em-websocket
@@ -75,7 +75,7 @@ dependencies:
75
75
  - - ! '>='
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
- description: Hara help you build async & concurrent websocket server.
78
+ description: Hara help you build async-io & concurrent websocket server.
79
79
  email:
80
80
  - jjyruby@gmail.com
81
81
  executables: []