puppeteer-rubyãæ±ãã¦ããåé¡
ããã¾ã§ã®puppeteer-rubyã§ã¯ãããªããèªåæä½ãæ¢ã¾ã£ã¦ãã¾ããããªããdocumentã¨ã¬ã¡ã³ããåå¾ã§ããè½ã¡ããã¨ããäºè±¡ãå¤çºãã¦ãããããããã«ãèªåæä½ã®å®èµ°çããã®ãããæªããããªããæã æ¢ã¾ã£ã¦ãã¾ããã¨ããææªãªç¶æ ã ã£ãã
ãããã®åå ã¯ãã»ã¼ã»ã¼WebSocketã®ã¬ã¹ãã³ã¹ãã³ããªã³ã°ã®é åºããªããåå¾ãã¦ãã¾ããã¨ã«èµ·å ãããã®ã ã£ãã
è¦ã¤ãããã³ã«ãã°ãå人Slacké¨å±ã«æä¸ãã¦ããã ãã©ã
å®ã«3ã¶æ以ä¸ãç´ããªãã§ããã
é çªãåå¾ãããã°ãç´ããªãããã®ããããè¨è¨...
CDPãããã³ã«ã®ãã³ããªã³ã°æã«ãSENDå®äºããå ã«RECVããã³ããªã³ã°ãããã...
def handle_message(message) if message['id'] if callback = @callbacks.delete(message['id']) callback_with_message(callback, message) else debug_puts "unknown id: #{id}. Store it into pending message" # RECV is often notified before SEND. # Wait about 10 frames before throwing an error. message_id = message['id'] @pending_messages[message_id] = message Concurrent::Promises.schedule(0.16, message_id) do |id| if @pending_messages.delete(id) raise Error.new("unknown id: #{id}") end end
Target.attachedã attachè¦æ±ãããå ã«å¦çãããã...
def create_session(target_info) result = send_message('Target.attachToTarget', targetId: target_info.target_id, flatten: true) session_id = result['sessionId'] # Target.attachedToTarget is often notified after the result of Target.attachToTarget. # D, [2020-04-04T23:04:30.736311 #91875] DEBUG -- : RECV << {"id"=>2, "result"=>{"sessionId"=>"DA002F8A95B04710502CB40D8430B95A"}} # D, [2020-04-04T23:04:30.736649 #91875] DEBUG -- : RECV << {"method"=>"Target.attachedToTarget", "params"=>{"sessionId"=>"DA002F8A95B04710502CB40D8430B95A", "targetInfo"=>{"targetId"=>"EBAB949A7DE63F12CB94268AD3A9976B", "type"=>"page", "title"=>"about:blank", "url"=>"about:blank", "attached"=>true, "browserContextId"=>"46D23767E9B79DD9E589101121F6DADD"}, "waitingForDebugger"=>false}} # So we have to wait for "Target.attachedToTarget" a bit. 20.times do if @sessions[session_id] return @sessions[session_id] end sleep 0.1 end end
ã
ã¨ãããããããããé åºãæ£ãããã³ããªã³ã°ã§ãã¦ããã°ãããªãã¨ããªãã¦ããããï¼ï¼ï¼ãã¨æãã¤ã¤ãããããªãããããã¸ãã¯ã§åé¿ããªããã3ã¶æ以ä¸ãéããã¦ããã®ã ã
socketry/async ããã©ã¤ããã...
Rubykaigi2019ã§ä½ã£ã人ãç´¹ä»ãã¦ããã ãã©ãRubyã®Fiberãã¼ã¹ã§éåæå¦çãå®ç¾ããã©ã¤ãã©ãªã
WebSocketãããã¤ã«ç½®ãæããã°ãã·ã³ã°ã«ã¹ã¬ããæä½ã«ãªãã®ã§äºè±¡ã¯æ¹åã§ãããã§ã¯ï¼ï¼ããã¨ããã£ããããã®ã©ã¤ãã©ãªã¯å¦ç¿ã³ã¹ããé«ãããã»ã»ã»ã»ã»ã»
ãããã試è¡é¯èª¤ãã¦ã¿ãããWebSocketã®readã§ã³ã±ã¦ã¿ããããããããã¯ãã¦ã¿ãã....
ãªãã¨ãªãã¡ãã»ã¼ã¸ã®ãã³ããªã³ã°ãåæå¦çã«ããããªãã£ãï¼
ç¹ã«çç±ã¯ãªããã ãããªãã¨ãªã
@transport.on_message do |data| async_handle_message(JSON.parse(data)) end
ããã§ãéåæã§æãã£ã±ãªãã®ã¨ãããã
@transport.on_message do |data| handle_message(JSON.parse(data)) end
åæã«ç½®ãæãã¦ã¿ããããã¨ããã³ããªã³ã°ãã·ã¼ã±ã³ã·ã£ã«ã«ãªãã®ã§ãèªåæä½é度ã¯ãã¡ããã¡ãé ããªãããäºè±¡ãå ¨ãçºçããªããªã£ã¦ãããã¨ã«æ°ãã¤ããã
ãããé åºãçã£ã¦ããåå ã¯ããã ã¨ãããã¨ãç¹å®ã§ããã
é©å½ã«sleepããã¦ã¿ããããã¯ããªãã£ãï¼
ã¨ã¯ããåæå¦çã§ã¯ãããããããªãªã¸ãã«ã®TypeScriptå®è£ ã§ããããã¯éåæå¼ã³åºãã ãRubyã§ã ãåæã«ããã®ã¯ã¤ã±ã¦ãªãã
ããããé©å½ã«sleepå ¥ãããã©ããªããã ãï¼
@transport.on_message do |data| sleep 0.1 handle_message(JSON.parse(data)) end
âãã»ã»ã»ãªãã£ã¦ãï¼ï¼
ããã§ãã³ã¨ããã
JSã¯ã·ã³ã°ã«ã¹ã¬ããã§ã(ä»ã®Chromiumã¯ç¥ããªãã) WebKitã§ã¯4msã®sharedTimerããããsetTimeoutãsetIntervalã4msåä½ã«ä¸¸ãããããï¼ã¨ããã®ã2014å¹´é ã«ãããããã³ã®ãã©ã¦ã¶éæ¹é ãã¦ãã¨ãã«ãã¾ãã¾ç¥ã£ã¦ããï¼
ãã¨ãããã¨ã¯ãããã§4mså¾ ã¦ã°ãã¨ãããããã¾ãããããããï¼ï¼ã
çµæã4mså¾ ãããã ãã§ãç´ã£ãï¼ï¼
ä¼ç¤¾ã®å¤æ 管çã·ã¹ãã ãå®é¨å°ã«ãã¦ã10åå®è¡ãã¦ã¿ãã¨ãããå®èµ°çã
- 0.0.10ã»ã»ã»2å/10å
- 0.0.11ã»ã»ã»10å/10å
å¤§å¹ ã«æ¹åããã
使ã£ã¦ã¿ã¦ãï¼
ä»ã¾ã§ã¯ç©æ¥µçã«èªæ ¢ã§ããªãå質ã ã£ããã©ã0.0.11ã§ã ãã¶çæ³ã«è¿ã¥ããã
ã¡ãã£ã¨ãã¤åºãã¦ããããã