catch-websocket-client 0.0.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.
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