websocket-eventmachine-client 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ Gemfile.lock
2
+ autobahn
3
+ pkg/*.gem
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ ## 1.0.0
4
+
5
+ - initial release
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem 'rake'
@@ -0,0 +1,208 @@
1
+ # WebSocket Client for Ruby
2
+
3
+ WebSocket-EventMachine-Client is Ruby WebSocket client based on EventMachine.
4
+
5
+ - [Autobahn tests](http://imanel.github.com/websocket-ruby/autobahn/client)
6
+ - [Docs](http://rdoc.info/github/imanel/websocket-eventmachine-client/master/frames)
7
+
8
+ ## Installation
9
+
10
+ ``` bash
11
+ gem install websocket-eventmachine-client
12
+ ```
13
+
14
+ or in Gemfile
15
+
16
+ ``` ruby
17
+ gem 'websocket-eventmachine-client'
18
+ ```
19
+
20
+ ## Simple client example
21
+
22
+ ```ruby
23
+ EM.run do
24
+
25
+ ws = WebSocket::EventMachine::Client.connect(:uri => 'ws://localhost:8080')
26
+
27
+ ws.onopen do
28
+ puts "Connected"
29
+ end
30
+
31
+ ws.onmessage do |msg, type|
32
+ puts "Received message: #{msg}"
33
+ end
34
+
35
+ ws.onclose do
36
+ puts "Disconnected"
37
+ end
38
+
39
+ ws.send "Hello Server!"
40
+
41
+ end
42
+ ```
43
+
44
+ ## Options
45
+
46
+ Following options can be passed to WebSocket::EventMachine::Client initializer:
47
+
48
+ - `[String] :host` - IP or host of server to connect
49
+ - `[Integer] :port` - Port of server to connect
50
+ - `[String] :uri` - Full URI for server(optional - use instead of host/port combination)
51
+ - `[Integer] :version` - Version of WebSocket to use. Default: 13
52
+
53
+ ## Methods
54
+
55
+ Following methods are available for WebSocket::EventMachine::Client object:
56
+
57
+ ### onopen
58
+
59
+ Called after successfully connecting.
60
+
61
+ Example:
62
+
63
+ ```ruby
64
+ ws.onopen do
65
+ puts "Client connected"
66
+ end
67
+ ```
68
+
69
+ ### onclose
70
+
71
+ Called after closing connection.
72
+
73
+ Example:
74
+
75
+ ```ruby
76
+ ws.onclose do
77
+ puts "Client disconnected"
78
+ end
79
+ ```
80
+
81
+ ### onmessage
82
+
83
+ Called when client receive message.
84
+
85
+ Parameters:
86
+
87
+ - `[String] message` - content of message
88
+ - `[Symbol] type` - type is type of message(:text or :binary)
89
+
90
+ Example:
91
+
92
+ ```ruby
93
+ ws.onmessage do |msg, type|
94
+ puts "Received message: #{msg} or type: #{type}"
95
+ end
96
+ ```
97
+
98
+ ### onerror
99
+
100
+ Called when client discovers error.
101
+
102
+ Parameters:
103
+
104
+ - `[String] error` - error reason.
105
+
106
+ Example:
107
+
108
+ ```ruby
109
+ ws.onerror do |error|
110
+ puts "Error occured: #{error}"
111
+ end
112
+ ```
113
+
114
+ ### onping
115
+
116
+ Called when client receive ping request. Pong request is sent automatically.
117
+
118
+ Parameters:
119
+
120
+ - `[String] message` - message for ping request.
121
+
122
+ Example:
123
+
124
+ ```ruby
125
+ ws.onping do |message|
126
+ puts "Ping received: #{message}"
127
+ end
128
+ ```
129
+
130
+ ### onpong
131
+
132
+ Called when client receive pong response.
133
+
134
+ Parameters:
135
+
136
+ - `[String] message` - message for pong response.
137
+
138
+ Example:
139
+
140
+ ```ruby
141
+ ws.onpong do |message|
142
+ puts "Pong received: #{message}"
143
+ end
144
+ ```
145
+
146
+ ### send
147
+
148
+ Sends message to server.
149
+
150
+ Parameters:
151
+
152
+ - `[String] message` - message that should be sent to client
153
+ - `[Hash] params` - params for message(optional)
154
+ - `[Symbol] :type` - type of message. Valid values are :text, :binary(default is :text)
155
+
156
+ Example:
157
+
158
+ ```ruby
159
+ ws.send "Hello Server!"
160
+ ws.send "binary data", :type => :binary
161
+ ```
162
+
163
+ ### close
164
+
165
+ Closes connection and optionally send close frame to server.
166
+
167
+ Parameters:
168
+
169
+ - `[Integer] code` - code of closing, according to WebSocket specification(optional)
170
+ - `[String] data` - data to send in closing frame(optional)
171
+
172
+ Example:
173
+
174
+ ```ruby
175
+ ws.close
176
+ ```
177
+
178
+ ### ping
179
+
180
+ Sends ping request.
181
+
182
+ Parameters:
183
+
184
+ - `[String] data` - data to send in ping request(optional)
185
+
186
+ Example:
187
+
188
+ ```ruby
189
+ ws.ping 'Hi'
190
+ ```
191
+
192
+ ### pong
193
+
194
+ Sends pong request. Usually there should be no need to send this request, as pong responses are sent automatically by client.
195
+
196
+ Parameters:
197
+
198
+ - `[String] data` - data to send in pong request(optional)
199
+
200
+ Example:
201
+
202
+ ``` ruby
203
+ ws.pong 'Hello'
204
+ ```
205
+
206
+ ## License
207
+
208
+ The MIT License - Copyright (c) 2012 Bernard Potocki
@@ -0,0 +1,16 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ # require 'rspec/core/rake_task'
5
+
6
+ # RSpec::Core::RakeTask.new do |t|
7
+ # t.rspec_opts = ["-c", "-f progress"]
8
+ # t.pattern = 'spec/**/*_spec.rb'
9
+ # end
10
+
11
+ # task :default => :spec
12
+
13
+ desc "Run autobahn tests for client"
14
+ task :autobahn do
15
+ system('wstest --mode=fuzzingserver --spec=autobahn.json')
16
+ end
@@ -0,0 +1,11 @@
1
+ {
2
+ "url": "ws://127.0.0.1:9001",
3
+
4
+ "options": {"failByDrop": false},
5
+ "outdir": "./autobahn",
6
+ "webport": 8080,
7
+
8
+ "cases": ["*"],
9
+ "exclude-cases": [],
10
+ "exclude-agent-cases": {}
11
+ }
@@ -0,0 +1,50 @@
1
+ require File.expand_path('../../lib/websocket-eventmachine-client', __FILE__)
2
+
3
+ require 'cgi'
4
+
5
+ EM.epoll
6
+ EM.run do
7
+
8
+ host = 'ws://localhost:9001'
9
+ agent = "WebSocket-EventMachine-Client (1.0.0)"
10
+ cases = 0
11
+ skip = []
12
+
13
+ ws = WebSocket::EventMachine::Client.connect(:uri => "#{host}/getCaseCount")
14
+
15
+ ws.onmessage do |msg, type|
16
+ puts "$ Total cases to run: #{msg}"
17
+ cases = msg.to_i
18
+ end
19
+
20
+ ws.onclose do
21
+
22
+ run_case = lambda do |n|
23
+
24
+ if n > cases
25
+ puts "$ Requesting report"
26
+ ws = WebSocket::EventMachine::Client.connect(:uri => "#{host}/updateReports?agent=#{CGI.escape agent}")
27
+ ws.onclose do
28
+ EM.stop
29
+ end
30
+
31
+ elsif skip.include?(n)
32
+ EM.next_tick { run_case.call(n+1) }
33
+
34
+ else
35
+ ws = WebSocket::EventMachine::Client.connect(:uri => "#{host}/runCase?case=#{n}&agent=#{CGI.escape agent}")
36
+
37
+ ws.onmessage do |msg, type|
38
+ ws.send(msg, :type => type)
39
+ end
40
+
41
+ ws.onclose do |msg|
42
+ EM.add_timer(0.1) { run_case.call(n + 1) }
43
+ end
44
+ end
45
+ end
46
+
47
+ run_case.call(1)
48
+ end
49
+
50
+ end
@@ -0,0 +1,42 @@
1
+ require File.expand_path('../../lib/websocket-eventmachine-client', __FILE__)
2
+
3
+ EM.epoll
4
+ EM.run do
5
+
6
+ trap("TERM") { stop }
7
+ trap("INT") { stop }
8
+
9
+ ws = WebSocket::EventMachine::Client.connect(:uri => "ws://localhost:9001");
10
+
11
+ ws.onopen do
12
+ puts "Connected"
13
+ ws.send "Hello"
14
+ end
15
+
16
+ ws.onmessage do |msg, type|
17
+ puts "Received message: #{msg}"
18
+ ws.send msg, :type => type
19
+ end
20
+
21
+ ws.onclose do
22
+ puts "Disconnected"
23
+ end
24
+
25
+ ws.onerror do |e|
26
+ puts "Error: #{e}"
27
+ end
28
+
29
+ ws.onping do |msg|
30
+ puts "Receied ping: #{msg}"
31
+ end
32
+
33
+ ws.onpong do |msg|
34
+ puts "Received pong: #{msg}"
35
+ end
36
+
37
+ def stop
38
+ puts "Terminating connection"
39
+ EventMachine.stop
40
+ end
41
+
42
+ end
@@ -0,0 +1 @@
1
+ require File.expand_path('../websocket/eventmachine/client', __FILE__)
@@ -0,0 +1,134 @@
1
+ require 'websocket-eventmachine-base'
2
+ require 'uri'
3
+
4
+ module WebSocket
5
+ module EventMachine
6
+
7
+ # WebSocket Client (using EventMachine)
8
+ # @example
9
+ # ws = WebSocket::EventMachine::Client.connect(:host => "0.0.0.0", :port => 8080)
10
+ # ws.onmessage { |msg| ws.send "Pong: #{msg}" }
11
+ # ws.send "data"
12
+ class Client < Base
13
+
14
+ ###########
15
+ ### API ###
16
+ ###########
17
+
18
+ # Connect to websocket server
19
+ # @param args [Hash] The request arguments
20
+ # @option args [String] :host The host IP/DNS name
21
+ # @option args [Integer] :port The port to connect too(default = 80)
22
+ # @option args [Integer] :version Version of protocol to use(default = 13)
23
+ def self.connect(args = {})
24
+ host = nil
25
+ port = nil
26
+ if args[:uri]
27
+ uri = URI.parse(args[:uri])
28
+ host = uri.host
29
+ port = uri.port
30
+ end
31
+ host = args[:host] if args[:host]
32
+ port = args[:port] if args[:port]
33
+ port ||= 80
34
+
35
+ ::EventMachine.connect host, port, self, args
36
+ end
37
+
38
+ # Initialize connection
39
+ # @param args [Hash] Arguments for connection
40
+ # @option args [String] :host The host IP/DNS name
41
+ # @option args [Integer] :port The port to connect too(default = 80)
42
+ # @option args [Integer] :version Version of protocol to use(default = 13)
43
+ def initialize(args)
44
+ @args = args
45
+ end
46
+
47
+ ############################
48
+ ### EventMachine methods ###
49
+ ############################
50
+
51
+ # Called after initialize of connection, but before connecting to server
52
+ # Eventmachine internal
53
+ # @private
54
+ def post_init
55
+ @state = :connecting
56
+ @handshake = WebSocket::Handshake::Client.new(@args)
57
+ end
58
+
59
+ # Called by EventMachine after connecting.
60
+ # Sends handshake to server
61
+ # Eventmachine internal
62
+ # @private
63
+ def connection_completed
64
+ send(@handshake.to_s, :type => :plain)
65
+ end
66
+
67
+ private
68
+
69
+ def incoming_frame
70
+ WebSocket::Frame::Incoming::Client
71
+ end
72
+
73
+ def outgoing_frame
74
+ WebSocket::Frame::Outgoing::Client
75
+ end
76
+
77
+ public
78
+
79
+ #########################
80
+ ### Inherited methods ###
81
+ #########################
82
+
83
+ # Called when connection is opened.
84
+ # No parameters are passed to block
85
+ def onopen(&blk); super; end
86
+
87
+ # Called when connection is closed.
88
+ # No parameters are passed to block
89
+ def onclose(&blk); super; end
90
+
91
+ # Called when error occurs.
92
+ # One parameter passed to block:
93
+ # error - string with error message
94
+ def onerror(&blk); super; end
95
+
96
+ # Called when message is received.
97
+ # Two parameters passed to block:
98
+ # message - string with received message
99
+ # type - type of message. Valid values are :text and :binary
100
+ def onmessage(&blk); super; end
101
+
102
+ # Called when ping message is received
103
+ # One parameter passed to block:
104
+ # message - string with ping message
105
+ def onping(&blk); super; end
106
+
107
+ # Called when pond message is received
108
+ # One parameter passed to block:
109
+ # message - string with pong message
110
+ def onpong(&blk); super; end
111
+
112
+ # Send data
113
+ # @param data [String] Data to send
114
+ # @param args [Hash] Arguments for send
115
+ # @option args [String] :type Type of frame to send - available types are "text", "binary", "ping", "pong" and "close"
116
+ # @option args [Integer] :code Code for close frame
117
+ # @return [Boolean] true if data was send, otherwise call on_error if needed
118
+ def send(data, args = {}); super; end
119
+
120
+ # Close connection
121
+ # @return [Boolean] true if connection is closed immediately, false if waiting for other side to close connection
122
+ def close(code = 1000, data = nil); super; end
123
+
124
+ # Send ping message
125
+ # @return [Boolean] false if protocol version is not supporting ping requests
126
+ def ping(data = ''); super; end
127
+
128
+ # Send pong message
129
+ # @return [Boolean] false if protocol version is not supporting pong requests
130
+ def pong(data = ''); super; end
131
+
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,7 @@
1
+ module WebSocket
2
+ module EventMachine
3
+ class Client
4
+ VERSION = '1.0.0'
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "websocket/eventmachine/client/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "websocket-eventmachine-client"
7
+ s.version = WebSocket::EventMachine::Client::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Bernard Potocki"]
10
+ s.email = ["bernard.potocki@imanel.org"]
11
+ s.homepage = "http://github.com/imanel/websocket-eventmachine-client"
12
+ s.summary = %q{WebSocket client for Ruby}
13
+ s.description = %q{WebSocket client for Ruby}
14
+
15
+ s.add_dependency 'websocket-eventmachine-base', '~> 1.0'
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: websocket-eventmachine-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Bernard Potocki
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-12-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: websocket-eventmachine-base
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.0'
30
+ description: WebSocket client for Ruby
31
+ email:
32
+ - bernard.potocki@imanel.org
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - CHANGELOG.md
39
+ - Gemfile
40
+ - README.md
41
+ - Rakefile
42
+ - autobahn.json
43
+ - examples/autobahn_client.rb
44
+ - examples/echo_client.rb
45
+ - lib/websocket-eventmachine-client.rb
46
+ - lib/websocket/eventmachine/client.rb
47
+ - lib/websocket/eventmachine/client/version.rb
48
+ - websocket-eventmachine-client.gemspec
49
+ homepage: http://github.com/imanel/websocket-eventmachine-client
50
+ licenses: []
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project:
69
+ rubygems_version: 1.8.24
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: WebSocket client for Ruby
73
+ test_files: []