websocket-eventmachine-client 1.0.0

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,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: []