Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Action Cableを使って 分報機能を実装しています

Action Cableを使って 分報機能を実装しています

This is the presentation I gave at the "First LT Meeting #2" for the students on May 9, 2020.

25d386a6d14efedc3d28190f9e39cb28?s=128

Kohei Takahashi

May 09, 2020
Tweet

Transcript

  1. ॳΊͯͷ-5ձ LPIFJUBLBIBTIJ "DUJPO$BCMFΛ࢖ͬͯ ෼ใػೳΛ࣮૷͍ͯ͠·͢

  2.  ࣗݾ঺հ  "DUJPO$BCMFͷੈք؍  ͲͷΑ͏ʹ࣮૷͍ͯ͠Δͷ͔  ·ͱΊ  ࢀߟαΠτ

    ˞Ͱ͖Δ͚ͩਖ਼֬ͳ಺༰Λ఻͑ΔΑ͏ʹ৺͕͚ͯ·͕͢ɺؒҧͬͨ಺༰Λ࿩ͯͨ͠Β͍͢·ͤΜ ˞ͦͷࡍ͸ڭ͑ͯͩ͘͞Δͱେม༗೉͍Ͱ͢ ͜ͷൃදͷ಺༰
  3. LPIFJUBLBITIJ ߴڮߤฏ ࡀ ஍ํͷେֶӃͰྟচ৺ཧΛษڧ͍͕ͯͨ͠ɺ࠳ંͯ͠ϓϩάϥϛϯάʹͨ·ͨ·ग़ձ͏ ͨ·ͨ·'+03%#005$".1Λݟ͚ͭɺ೥݄ʹೖձ ೥݄͔Βबۀ༧ఆ झຯ͸ϘʔυήʔϜͱಡॻͱԹઘ ݈߁ϥϯυ  ࠓ͸εΫϥϜ։ൃͱࣗ࡞ΞϓϦ։ൃʹऔΓ૊ΜͰ͍·͢

    ࣗݾ঺հ
  4. ෼ใػೳΛ࣮૷த ࣗ෼΍ଞͷਓͷ౤ߘΛݟΔͨΊʹɺҰճҰճϖʔδΛϦ ϩʔυͨ͘͠ͳ͍ɻ ͦͷͨΊɺϖʔδϦϩʔυͳ͠ͰϦΞϧλΠϜʹ౤ߘɺฤ ूɺ࡟আ͕දࣔ͞ΕΔΑ͏ʹ͍ͨ͠ɻ ͦͷϦΞϧλΠϜදࣔΛ࣮ݱ͢ΔͨΊʹ 伴ͱͳͬͯ͘Δͷ͕૒ํ޲௨৴

  5. ૒ํ޲௨৴Λ࣮ݱ͢ΔͨΊʹ 3BJMT͕ఏڙ͍ͯ͠ΔϑϨʔϜϫʔΫ͕ "DUJPO$BCMF

  6. Ұ౓ίωΫγϣϯཱ͕֬͞ΕΔͱɺઐ༻ͷϓϩτίϧ্Ͱ΍ΓͱΓΛߦ͏Α͏ʹͳΓ·͢ɻ͜ ΕʹΑΓɺແཧͳ͘૒ํ޲௨৴͕Ͱ͖ΔΑ͏ʹͳΓ·ͨ͠ɻ "DUJPO$BCMFͰ͸8FC4PDLFU௨৴͕Ͱ͖Δ )551ίωΫγϣϯ 8FC4PDLFUίωΫγϣϯ

  7. ΫϥΠΞϯτ͕αʔόʔʹϦΫΤετΛૹΓɺͦΕʹԠ౴ͯ͠ɺαʔόʔଆ͕ϨεϙϯεΛฦ ͢͜ͱ͕લఏͷͨΊɺϦΫΤετͳ͠Ͱαʔόʔଆ͕ೳಈతʹσʔλΛૹΔ͜ͱ͕Ͱ͖·ͤΜ Ͱͨ͠ɻ 9.-3FRVFTU௨৴Ͱ͸ ϦΫΤετ Ϩεϙϯε

  8. $PNFU௨৴Ͱ͸ ͦ΋ͦ΋)551ίωΫγϣϯ͸ɺϦΫΤετΛૹͬͯϨεϙϯε͕ฦ͖ͬͯͨΒΫ ϩʔζ͢ΔͨΊɺ͜ΕΛҙਤతʹΫϩʔζͤ͞ͳ͍͜ͱͰɺ૒ํ޲௨৴Λ࣮ݱ͠Α͏ ͱͨ͠ͷ͕$PNFU௨৴Ͱ͢ɻ )551ίωΫγϣϯͷຊདྷͷ࢖͍ํͱ͸ҟͳΔͨΊɺཪٕతͳ΋ͷͷΑ͏Ͱ͢ɻ )551ίωΫγϣϯ

  9. "DUJPO$BCMFͷੈք؍

  10. "DUJPO$BCMFͷੈք؍ 8FC4PDLFUίωΫγϣϯ DPOTVNFS DIBOOFM EBUB ΫϥΠΞϯτ αʔόʔ

  11. 8FC4PDLFUίωΫγϣϯͷத 8FC4PDLFUίωΫγϣϯ DIBOOFM EBUB DPOTVNNFS͕DIBOOFMʹೖΓɺσʔ λड͚औΓՄೳঢ়ଶʹͳΔ͜ͱΛ TVCTDSJCFͱ͍͏ DPOTVNFS EBUB͕DIBOOFMʹૹΒΕͯɺ DPOTVNFS͕डऔՄೳঢ়ଶʹͳΔ͜ͱΛ

    CSPBEDBTUͱ͍͏
  12. ݱஈ֊ͷ෼ใػೳΛ͓ݟͤ͠·͢

  13. ͜Ε͸ͲͷΑ͏ʹ࣮૷ͨ͠ͷ͔

  14. ෼ใϖʔδΛ։͍ͨ࣌ͷॲཧͷྲྀΕ 7VFίϯϙʔωϯτ UJNFMJOFT@DIBOOFMWVF UJNFMJOFWVF 7VFKTଆ 3BJMTଆ BQQDIBOOFMT DIBOOFMSC DPOOFDUJPOSC BQQMJDBUJPO@DBCMF

    UJNFMJOFT@DIBOOFMSC ᶆαϒεΫϥΠϒ͞ΕͨΒɺ աڈͷ෼ใҰཡͷσʔλΛૹΔ ᶃίϯϙʔωϯτ͕DSFBUF͞Εͨ࣌ʹ 8FC4PDLFUίωΫγϣϯΛ࡞Ζ͏ͱ͢Δ ᶄDVSSFOU@VTFSͳΒ ίωΫγϣϯΛཱ֬͢Δ ᶅίωΫγϣϯཱ͕֬͞ΕͨΒ αϒεΫϥΠϒ͢Δ
  15. 7VFίϯϙʔωϯτ UJNFMJOFT@DIBOOFMWVF UJNFMJOFWVF 7VFKTଆ 3BJMTଆ BQQDIBOOFMT DIBOOFMSC DPOOFDUJPOSC BQQMJDBUJPO@DBCMF UJNFMJOFT@DIBOOFMSC

  16. 8FC4PDLFUίωΫγϣϯͷཱ֬ʹؔ͢Δॲཧ Λهड़͍ͯ͠·͢ɻ ͜͜Ͱ͸ɺJEFOUJGJFE@CZͰ8FC4PDLFUίω ΫγϣϯʹJEΛ༩͍͑ͯ·͢ɻ ͜͜Ͱ͸ɺDVSSFOU@VTFSΛίωΫγϣϯͷJE ʹ͍ͯ͠·͢ɻ DPPLJF͔ΒDVSSFOU@VTFSͷ৘ใΛಡΈऔͬ ͍ͯ·͢ɻ΋͠ɺDPPLJFʹDVSSFOU@VTFSͷ ৘ใ͕ͳ͚Ε͹ɺίωΫγϣϯΛཱ֬͠·ͤ Μɻ

    DPOOFDUJPOSCΛݟ͍ͯ͘ ۩ମతͳίʔυ͕ཉ͍͠ module ApplicationCable class Connection < ActionCable::Connection::Base identified_by :current_user def connect self.current_user = find_verified_user end private def find_verified_user if verified_user = User.find_by(id: store["user_id"]) verified_user else reject_unauthorized_connection end end def store cookies.encrypted[Rails.application.config.session_options[:key]] end end end
  17. 7VFίϯϙʔωϯτ UJNFMJOFT@DIBOOFMWVF UJNFMJOFWVF 7VFKTଆ 3BJMTଆ BQQDIBOOFMT DIBOOFMSC DPOOFDUJPOSC BQQMJDBUJPO@DBCMF UJNFMJOFT@DIBOOFMSC

  18. "DUJPO$BCMFͷDIBOOFMʹ͓͚Δ DPOUSPMMFSͷ໾ׂΛ୲͍·͢ɻ ͦͷͨΊɺ$36%ͷॲཧΛهड़ͯ͠· ͢ɻ σʔλΛϒϩʔυΩϟετ͢Δ͜ͱͰɺ νϟωϧʹσʔλΛૹΓ·͢ɻ ·ͨɺαϒεΫϥΠϒͨ࣌͠΍ɺαϒε ΫϥΠϒ͕ऴΘͬͨ࣌ͷॲཧΛॻ͖· ͢ɻ ͜͜Ͱ͸ɺαϒεΫϥΠϒͨ࣌͠ʹɺա

    ڈͷ෼ใҰཡΛૹΔΑ͏ʹ͍ͯ͠·͢ɻ UJNFMJOFT@DIBOOFMSCΛݟ͍ͯ͘ ۩ମతͳίʔυ͕ཉ͍͠ class TimelinesChannel < ApplicationCable::Channel include Rails.application.routes.url_helpers def subscribed stream_from "timelines_channel" timelines = Timeline.order(created_at: :asc) transmit({ event: "timelines", current_user: format_current_user, timelines: format_timelines(timelines) }) end def unsubscribed # Any cleanup needed when channel is unsubscribed end def create_timeline(data) @timeline = Timeline.create!(user_id: current_user.id, description: data["description"]) ActionCable.server.broadcast "timelines_channel", { event: "create_timeline", timeline: format_timeline(@timeline) } end def update_timeline(data) @timeline = Timeline.find_by(id: data["id"]) @timeline.update(description: data["description"]) ActionCable.server.broadcast "timelines_channel", { event: "update_timeline", timeline: format_timeline(@timeline) } end def delete_timeline(data) @timeline = Timeline.find_by(id: data["id"]) @timeline.destroy ActionCable.server.broadcast "timelines_channel", { event: "delete_timeline", timeline: format_timeline(@timeline) } end end
  19. 7VFίϯϙʔωϯτ UJNFMJOFT@DIBOOFMWVF UJNFMJOFWVF 7VFKTଆ 3BJMTଆ BQQDIBOOFMT DIBOOFMSC DPOOFDUJPOSC BQQMJDBUJPO@DBCMF UJNFMJOFT@DIBOOFMSC

  20. ෼͔Γ΍͍͢Α͏ʹҰ෦ൈਮͱɺվมΛߦ͍ͬͯ ·͢ɻ ͜͜ʹɺϑϩϯτΤϯυଆͷUJNFMJOF@DIBOOFM ʹؔ͢Δ৘ใ͕·ͱ·͍ͬͯ·͢ CSPBEDBTU͞Εͨσʔλ͸\BDUJPODSFBUF  UJNFMJOF!UJNFMJOF^ͳͲͷܗͰૹΔΑ͏ʹ͠ ͍ͯ·͢ɻ ͦ͜Ͱɺड͚औͬͨσʔλͷBDUJPO͕ͳΜͳͷ ͔ͰɺॲཧΛม͑ΔΑ͏ʹ͍ͯ͠·͢ɻ

    UJNFMJOFTDIBOOFMWVFΛݟ͍ͯ͘ this.timelinesChannel = this.$cable.subscriptions.create("TimelinesChannel", { connected: () => { console.log('connected successfully') }, disconnected: () => { }, received: (data) => { switch (data.event) { case 'timelines': data.timelines.forEach((timeline) => { this.timelines.unshift(timeline) }) break case 'create_timeline': this.timelines.unshift(data.timeline) break case 'update_timeline': this.timelines.forEach((timeline) => { if (timeline.id === data.timeline.id) { timeline.description = data.timeline.description } }) break case 'delete_timeline': this.timelines.forEach((timeline, i) => { if (timeline.id === data.timeline.id) { this.timelines.splice(i, 1) } }) break } } })
  21. "DUJPO$BCMFͷੈք؍Λ௫Ήͷ͕ͱͯ΋େมͰͨ͠ɻͦ͜ͰɺͦͷഎܠͱͳΔ8FC4PDLFU ͷ֓ཁΛֶͿ͜ͱͰɺͣͬͱཧղ͠΍͘͢ͳΓ·ͨ͠ɻ +BWB4DSJQUଆͰDIBOOFMͰఆٛ͞ΕͨϝιουΛݺ΂ͨΓɺϝιουҰͭͰɺσʔλΛૹΕ ͨΓ͢ΔͷͰɺ3BJMTͱ7VFKTͷσʔλͷ΍ΓऔΓ͕ൺֱత؆୯ʹͰ͖·ͨ͠ɻ खܰʹϦΞϧλΠϜͷΞΫγϣϯ͕࣮૷Ͱ͖ΔҰํͰɺগ͠खͷࠐΜͩ͜ͱΛ΍Ζ͏ͱ͢Δ ͱɺͱͯ΋ϋϚΓ·ͨ͠ ࣗ෼ͷྗෆ଍ͳ͚ͩͰ͕͢ʜ ɻ ͋ͱগ͠Ͱ13Λग़ͤΔͷͰ͕͢ɺͦͷগ͠ͷͱ͜ΖͰ֨ಆதͰ͢ɻ ۩ମతʹͲΜͳͱ͜ΖʹϋϚͬͨͷ͔ɺۤ͠Μͩͷ͔͸ޙ೔ϒϩάʹॻ͖͍ͨͱࢥ͍·͢ɻ

    ·ͱΊ
  22. 3BJMTΨΠυd"DUJPO$BCMFͷ֓ཁd IUUQTSBJMTHVJEFTKQ BDUJPO@DBCMF@PWFSWJFXIUNM  8FC4PDLFU IUUQTKBXJLJQFEJBPSHXJLJ8FC4PDLFU  ࣮ࡍͷ13͸ͪ͜Β IUUQTHJUIVCDPNGKPSEMMDCPPUDBNQQVMM ࢀߟʹ͍͍ͤͯͨͩͨ͞αΠτ౳

  23. ͝੩ௌ༗Γ೉͏͍͟͝·ͨ͠