Class: SlackSocketModeBot::SimpleWebSocket
- Inherits:
-
Object
- Object
- SlackSocketModeBot::SimpleWebSocket
- Defined in:
- lib/slack_socket_mode_bot/simple_web_socket.rb
Instance Method Summary collapse
- #close(code: 1000, reason: "") ⇒ Object
-
#initialize(url) ⇒ SimpleWebSocket
constructor
A new instance of SimpleWebSocket.
- #send(data, type: :text, code: nil) ⇒ Object
- #step(read_ios, write_ios) ⇒ Object
Constructor Details
#initialize(url) ⇒ SimpleWebSocket
Returns a new instance of SimpleWebSocket.
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/slack_socket_mode_bot/simple_web_socket.rb', line 2 def initialize(url) uri = URI.parse(url) unless uri.scheme == "https" || uri.scheme == "wss" raise "unexpected scheme (not secure?): #{ uri.scheme }" end ctx = OpenSSL::SSL::SSLContext.new ctx.ssl_version = "SSLv23" ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER ctx.cert_store = OpenSSL::X509::Store.new ctx.cert_store.set_default_paths count = 0 begin io = TCPSocket.new(uri.host, uri.port || 443) @io = OpenSSL::SSL::SSLSocket.new(io, ctx) @io.connect rescue Socket::ResolutionError sleep 1 count += 1 retry if count < 3 raise end @version = nil @fib = Fiber.new do closed = false begin handshake = WebSocket::Handshake::Client.new(url: url) @write_buff = handshake.to_s.dup handshake << Fiber.yield until handshake.finished? @version = handshake.version yield :open frame = WebSocket::Frame::Incoming::Client.new frame << handshake.leftovers while true while msg = frame.next case msg.type when :close yield :close unless closed closed = true when :ping send(msg.data, type: :pong) when :pong when :text yield :message, msg.data, :text when :binary yield :message, msg.data, :binary end end frame << Fiber.yield end rescue EOFError ensure yield :close unless closed @io.close end end @fib.resume end |
Instance Method Details
#close(code: 1000, reason: "") ⇒ Object
74 75 76 |
# File 'lib/slack_socket_mode_bot/simple_web_socket.rb', line 74 def close(code: 1000, reason: "") send(reason, type: :close, code: code) unless @io.closed? end |
#send(data, type: :text, code: nil) ⇒ Object
68 69 70 71 72 |
# File 'lib/slack_socket_mode_bot/simple_web_socket.rb', line 68 def send(data, type: :text, code: nil) raise "not opened yet" unless @version frame = WebSocket::Frame::Outgoing::Client.new(version: @version, data: data, type: type, code: code) @write_buff << frame.to_s end |
#step(read_ios, write_ios) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/slack_socket_mode_bot/simple_web_socket.rb', line 78 def step(read_ios, write_ios) wait_readable = wait_writable = false unless @write_buff.empty? len = @io.write_nonblock(@write_buff, exception: false) case len when :wait_readable then wait_readable = true when :wait_writable then wait_writable = true else @write_buff.clear end end while true read_buff = @io.read_nonblock(4096, exception: false) case read_buff when :wait_readable then wait_readable = true; break when :wait_writable then wait_writable = true; break when nil raise Errno::EPIPE else @fib.resume(read_buff) end end read_ios << @io if wait_readable write_ios << @io if wait_writable return true rescue Errno::EPIPE, Errno::ECONNRESET begin @fib.raise(EOFError) rescue FiberError end return false end |