lib/binance/websocket_base.rb
# frozen_string_literal: true require 'logger' require 'websocket-eventmachine-client' module Binance # Base Websocket class WebSocketBase def initialize(options = {}) @logger = options[:logger] || Logger.new($stdout) @base_url = options[:base_url] @ws_connection = nil end def create_connection(url, cbs) @ws_connection = ::WebSocket::EventMachine::Client.connect(uri: url) add_callbacks(cbs) end def subscribe_to(url, cbs) create_connection(url, cbs) end private def add_callbacks(cbs) # check allowed callbacks raise ArgumentError, 'Only :onopen, :onmessage, :onclose, :onping, :onpong, :onerror allowed' if %i[onopen onmessage onping onpong onerror onclose].union(cbs.keys).size > 6 onmessage(cbs) onerror(cbs) onping(cbs) onpong(cbs) onclose(cbs) end def onopen(cbs) @ws_connection.onopen do @logger.debug('connected to server') event_callback(cbs, :onopen) end end def onmessage(cbs) @ws_connection.onmessage do |msg, type| cbs[:onmessage].call(msg, type) if cbs.key?(:onmessage) && cbs[:onmessage].respond_to?(:call) end end def onerror(cbs) @ws_connection.onerror do |error| @logger.error("Error occured: #{error}") event_callback(cbs, :onerror, error) end end def onping(cbs) @ws_connection.onping do @logger.info('Received ping from server') @ws_connection.pong @logger.info('Responded pong to server') event_callback(cbs, :onping) end end def onpong(cbs) @ws_connection.onpong do @logger.info('Received pong from server') event_callback(cbs, :onpong) end end def onclose(cbs) @ws_connection.onclose do @logger.info('Closed from server') event_callback(cbs, :onclose) end end def event_callback(cbs, event, data = nil) cbs[event].call(data) if cbs.key?(event) && cbs[event].respond_to?(:call) end end end