catch-websocket-client 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 53f1aa32e229515ee979769d54b7da55f048cd91d9c4675f0d28244fc67ef2df
4
+ data.tar.gz: 7705308c275bb4b98c32be0d29198169b64776d49a1e9a4965a455340ff2bff2
5
+ SHA512:
6
+ metadata.gz: 77210f270f80d80d338bbf87549b216045e2a9c69910fe04f8fc0a11e83ecf728f91d9c626eaf28a530f9103df015e601b151538b1548bf16ff633083d8de2f9
7
+ data.tar.gz: c00d8fdadeb7b5413320b3329fa24ac32a10f811acbece1a47495a571ae8d002bcf3b1abebd1505c6d7143138cf83d7b79dc13c29538b52e965da1e6a1eece55
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ *.gem
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ catch-websocket-client
2
+ ======================
3
+ This is a library for interactive WebSocket communication like HTTP.
4
+ Once you send a request, it will keep waiting for a response.
5
+
6
+
7
+ Usage
8
+ -----
9
+ ## Case. 1
10
+ ```ruby
11
+ require 'catch-websocket-client'
12
+
13
+ cws = CatchWebSocket::Client.new 'wss://example.com'
14
+
15
+ response = cws.request({
16
+ command: :auth,
17
+ params: {
18
+ id: 'username',
19
+ pw: 'password'
20
+ }
21
+ })
22
+
23
+ result = JSON.parse(response)
24
+
25
+ puts JSON.pretty_generate(result)
26
+ ```
27
+
28
+
29
+ ## Case. 2
30
+ ```ruby
31
+ require 'catch-websocket-client'
32
+
33
+ result = nil
34
+ CatchWebSocket::Client.open('wss://example.com') { |socket|
35
+ socket.request({
36
+ }) { |result|
37
+ result = JSON.parse(result)
38
+ if result['chunk']
39
+ results = []
40
+ while true
41
+ results[result['seq']] = result['chunk']
42
+ break if result['last']
43
+ result = JSON.parse(socket.receive)
44
+ end
45
+ result = JSON.parse(results.join)
46
+ end
47
+ }
48
+ }
49
+
50
+ puts JSON.pretty_generate(result)
51
+ ```
52
+
53
+ ## Copyright
54
+
55
+ Copyright c 2022 @neirouter
56
+ LICENSE: MIT License
57
+
@@ -0,0 +1,31 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'catch-websocket-client/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'catch-websocket-client'
7
+ spec.version = CatchWebSocket::VERSION
8
+ spec.authors = ['nierouter']
9
+ spec.email = ['nierouter@gmail.com']
10
+ spec.description = 'This client sends a request and waits for a response, just like HTTP communication.'
11
+ spec.summary = 'Catch WebSocket Client for Ruby'
12
+ spec.homepage = 'https://github.com/nierouter/catch-websocket-client'
13
+ spec.license = 'MIT'
14
+ spec.required_ruby_version = '>= 2.7.5'
15
+
16
+ if spec.respond_to?(:metadata)
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = spec.homepage
19
+ end
20
+
21
+ spec.files = `git ls-files`.split($/).reject{|f| f == "Gemfile.lock" }
22
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
23
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_dependency 'json', '~> 2.6.1'
27
+ spec.add_dependency 'openssl', '~> 3.0.0'
28
+ spec.add_dependency 'timeout', '~> 0.2.0'
29
+ spec.add_dependency 'uri', '~> 0.11.0'
30
+ spec.add_dependency 'websocket', '~> 1.2.9'
31
+ end
@@ -0,0 +1,85 @@
1
+ module CatchWebSocket
2
+
3
+ #
4
+ class Client
5
+ FrameTimeoutSec = 600
6
+ def self.open url, type=nil
7
+ client = CatchSocket.new url, type
8
+ if block_given?
9
+ begin
10
+ yield client
11
+ rescue => e
12
+ client.close
13
+ raise e
14
+ end
15
+ client.close
16
+ client = nil
17
+ end
18
+ return client
19
+ end
20
+
21
+ attr_reader :uri, :is_closed
22
+
23
+ def initialize url, type=nil
24
+ @uri = URI.parse url
25
+ @type = type || :text
26
+ ctx = OpenSSL::SSL::SSLContext.new
27
+ ctx.ssl_version = 'SSLv23'
28
+ ctx.options = OpenSSL::SSL::OP_NO_SSLv2
29
+ cert_store = OpenSSL::X509::Store.new
30
+ cert_store.set_default_paths
31
+ ctx.cert_store = cert_store
32
+ @socket = ::OpenSSL::SSL::SSLSocket.new(TCPSocket.new(@uri.host, @uri.port || 443), ctx)
33
+ @socket.connect
34
+ write_and_receive(@handshake = ::WebSocket::Handshake::Client.new(url: url))
35
+ @frame = ::WebSocket::Frame::Incoming::Client.new
36
+ @is_closed = false
37
+ end
38
+ def close
39
+ return if @is_closed
40
+ write_and_receive(nil, :close)
41
+ begin
42
+ @socket.close
43
+ rescue => e
44
+ raise e
45
+ end
46
+ @is_closed = true
47
+ end
48
+ def request message
49
+ unless @is_closed
50
+ message = JSON.generate(message) if message.is_a?(Hash) || message.is_a?(Array)
51
+ result = write_and_receive(message, @type)
52
+ if block_given?
53
+ yield result
54
+ else
55
+ return result
56
+ end
57
+ end
58
+ end
59
+ def write_and_receive message, type=nil
60
+ @last_message = message
61
+ message = ::WebSocket::Frame::Outgoing::Client.new(data: message, type: type, version: @handshake.version) if type
62
+ @socket.write message.to_s
63
+ receive
64
+ end
65
+ def receive
66
+ while true
67
+ character = nil
68
+ counter = 0
69
+ while (character = @socket.getc).nil?
70
+ sleep 0.1
71
+ counter += 1
72
+ raise Timeout::Error.new("FrameTimeout: #{@last_message}") if FrameTimeoutSec <= counter
73
+ end
74
+ if @frame.nil?
75
+ @handshake << character
76
+ return if @handshake.finished?
77
+ else
78
+ @frame << character
79
+ incoming = @frame.next
80
+ return incoming.data if incoming
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,3 @@
1
+ module CatchWebSocket
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,11 @@
1
+ require 'json'
2
+ require 'openssl'
3
+ require 'timeout'
4
+ require 'uri'
5
+ require 'websocket'
6
+
7
+ require 'catch-websocket-client/version'
8
+ require 'catch-websocket-client/client'
9
+
10
+ module CatchWebSocket
11
+ end
data/test/sample.rb ADDED
@@ -0,0 +1,18 @@
1
+ lib = 'lib'
2
+ lib = File.expand_path((File.exist?(lib) ? '' : '../').concat(lib), __dir__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'catch-websocket-client'
5
+
6
+ cws = CatchWebSocket::Client.new 'wss://websocket.nierouter.com/'
7
+
8
+ response = cws.request({
9
+ method: :auth,
10
+ params: {
11
+ user: 'nierouter',
12
+ pass: 'nierouter'
13
+ }
14
+ })
15
+
16
+ result = JSON.parse(response)
17
+
18
+ puts JSON.pretty_generate(result)
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: catch-websocket-client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - nierouter
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-01-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.6.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.6.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: openssl
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 3.0.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.0.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: timeout
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.2.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.2.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: uri
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.11.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.11.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: websocket
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.2.9
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.2.9
83
+ description: This client sends a request and waits for a response, just like HTTP
84
+ communication.
85
+ email:
86
+ - nierouter@gmail.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - README.md
93
+ - catch-websocket-client.gemspec
94
+ - lib/catch-websocket-client.rb
95
+ - lib/catch-websocket-client/client.rb
96
+ - lib/catch-websocket-client/version.rb
97
+ - test/sample.rb
98
+ homepage: https://github.com/nierouter/catch-websocket-client
99
+ licenses:
100
+ - MIT
101
+ metadata:
102
+ homepage_uri: https://github.com/nierouter/catch-websocket-client
103
+ source_code_uri: https://github.com/nierouter/catch-websocket-client
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: 2.7.5
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ requirements: []
119
+ rubygems_version: 3.3.3
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: Catch WebSocket Client for Ruby
123
+ test_files:
124
+ - test/sample.rb