Next.jsãšMomento ð¯ã䜿ã£ãã€ã³ã¿ã©ã¯ãã£ããªã©ã€ããªã¢ã¯ã·ã§ã³ã¢ããªã®æ§ç¯
çµµæåã®ãªã¢ã¯ã·ã§ã³ã§èŽè¡ãæ¹ãã€ãã
察é¢ã§ãã¬ãŒã³ããŒã·ã§ã³ãããããšãããã ãããã話ããªããéšå±ãèŠæž¡ããšãããªããããã¡ã¢ãåã£ããããŠãã人ãããã誰ããæãæããŠãããªããèšã£ãããšã«ã€ããŠè³ªåãããããããªããçžæãçŽæ¥èŠãããšãã§ããã°ãçžæã®é¢å¿ãåŒãã®ã¯æ¬åœã«ç°¡åã§ãã
ãããããªã³ã©ã€ã³ã»ãã¬ãŒã³ããŒã·ã§ã³ã¯å°ãé£ãããã®ã§ããããªãã¯ïŒäžè¬çã«ïŒãã¬ãŒã³ããçžæãèŠãããšãã§ããŸãããäžäººã§ãªããŒãµã«ãããŠããŠãã1000人ã®èŽè¡ã«åãã£ãŠãã¬ãŒã³ãããŠããŠãããŸã£ããåãããã«æããŸããããªããšèŽè¡ã®éã«ã¯æ絶ããããããªããããŸããã£ãŠããã®ãããããšã倱æããŠããã®ããç¥ãããšãã§ããªãã®ã§ãã
æ°ã¶æåã Michael Liendo ã®æçš¿ãç®ã«ããŸããã圌ã¯ãã¢ããã«ã®KeynoteãšWebSocketã䜿ã£ãŠããã¬ãŒã³ããŒã·ã§ã³ã®ãšã³ã²ãŒãžã¡ã³ããæ倧éã«é«ããŠããŸããã圌ã¯ãèŽè¡ã®ã¡ã³ããŒããã¬ãŒã³ããŒã·ã§ã³äžã«ãªã¢ã«ã¿ã€ã ã§ã¹ã¯ãªãŒã³ã«çµµæåãéãããšãã§ãããŠã§ããµã€ããæ§ç¯ããããªããŠã¯ãŒã«ãªãã§ãããïŒ
ç§ãããã欲ããã£ãïŒã³ã¡ã³ããéãæ©èœãè¿œå ããããšæããŸãããããã§åœŒã®ããã°èšäºãèªãã§ãããã«ã€ã³ã¹ãã¬ãŒã·ã§ã³ãåãããã ãã©ãåé¡ããããŸãããç§ã¯Macãæã£ãŠããªãã®ã§ïŒããã£ãŠãããããã£ãŠããïŒãKeynoteã䜿ãããšãã§ããŸãããããã«ã圌ã®ãã¶ã€ã³ã¯AWSã³ã³ãœãŒã«ã䜿ã£ãŠAppSyncã§WebSocket APIãäœããšãããã®ã§ãããããã¯1ã€ã®ãã¬ãŒã³ããŒã·ã§ã³ãšããŠã¯ä¿¡ããããªãã»ã©ã¯ãŒã«ã ããããŸãã¹ã±ãŒã«ããããã«ã¯æããŸããã§ããã
ç§ã¯ãã§ã«ãããããå¿ èŠä»¥äžã«ãã¬ãŒã³ããŒã·ã§ã³ã®æ§ç¯ã«åŽåãè²»ãããŠãããæ¯åæ¯åã芳客ã®ãšã³ã²ãŒãžã¡ã³ããé«ããããã«ãŠã§ãã¢ããªãäœãçŽãäœè£ã¯ãããŸããããããªæéãããã°ããã®ã§ãããçŸå®ã¯ããã§ã¯ãããŸããããã®ããšã念é ã«çœ®ããŠãç§ã¯ãã€ã±ã«ã®é©ç°çãªã¢ã€ãã¢ã匷åããããã®ããã€ãã®èŠä»¶ãæã£ãŠããŸããïŒ
ã»Googleã¹ã©ã€ããšã®äºææ§ïŒç¡æãå«ããªäººã¯ããªãã§ãããïŒïŒã
ã»ãã¬ãŒã³ããŒã·ã§ã³ãæ§ç¯ããªããåçã«ãµããŒã
ã»ã¢ãŒããã¯ãã£ãšãããã€ã®èŠä»¶ãæå°éã«æãã
ã»ãã¬ãŒã³ããŒã·ã§ã³ã®æåŸã«æ¥œããçµ±èšã衚瀺ãã
ãããã®èŠä»¶ãæºããããã«ãç§ãã©ã®ããã«ã©ã€ããªã¢ã¯ã·ã§ã³ã¢ããªãäœã£ããèŠãŠã¿ãŸãããã
ã°ãŒã°ã«ã»ã¹ã©ã€ãã®ãµããŒã
PowerPointãKeynoteã䜿ã£ãŠãã¬ãŒã³ããŒã·ã§ã³ãäœã£ãããšããã人ãªããGoogleã¹ã©ã€ããããã§ãªãããšã¯ãããã ãããæ©èœãã¢ãã¡ãŒã·ã§ã³ã¯éãããŠãããããã®åãšãŠãããã§ããŠããããããç¡æã§ãçŽ æŽããããªã³ã©ã€ã³ã»ã³ã©ãã¬ãŒã·ã§ã³æ©èœãåããŠããŸãããã§ã«KeynoteãPowerPointã®ãã¬ãŒã³ããŒã·ã§ã³ãæã£ãŠãããªããGoogleã¹ã©ã€ãã«åé¡ãªãã€ã³ããŒãã§ããŸãã
ãã®ã¢ããªã®ãã«ãã«çæãããšããç§ã¯2ã€ã®ããšã念é ã«çœ®ããŠããŸããããã¬ãŒã³ããŒã·ã§ã³ã®htmlãããããªãããã«ããããšãšãè€æ°ã®äœæè ã«ãããã¬ãŒã³ããŒã·ã§ã³ãèš±å¯ããããšã§ããããã§Slidesã®ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ããããã調ã¹ãPublish to Webæ©èœã䜿ã£ãŠãã¬ãŒã³ããŒã·ã§ã³ãäžè¬å ¬éããæ¹æ³ãèŠã€ããŸããã
ãã¬ãŒã³ããŒã·ã§ã³ããŠã§ãã«å ¬éããéãåã蟌ããªãã·ã§ã³ãæäŸãããŸããããã«ãããã¹ã©ã€ããžã®ãªã³ã¯ãå«ãiframeãäœæãããŸãããããä»»æã®ãŠã§ãããŒãžã«ããããããã°ãã¢ããªã§ãã¹ããããŠããã¹ã©ã€ãããã®ãŸãŸèŠãããšãã§ããŸãïŒåã蟌ã¿ã³ãŒããããèŠãŠã¿ããšãç¹ã«äŸ¿å©ãªããšã«æ°ã¥ããŸããïŒ
ããã¯ãã©ã¡ãŒã¿åã§ããããã«èŠããŸããïŒãã¬ãŒã³ããŒã·ã§ã³IDã¯ãURLã®https://docs.google.com/presentation/d/e/
ãã€ãŸããNext.jsã¢ããªã®ããŒãžã«iframeãããããããŠãsrcèŠçŽ ããã©ã¡ãŒã¿åããŠããã¬ãŒã³ããŒã·ã§ã³ãæ±çšçã«ã¬ã³ããªã³ã°ããã°ããã£ãã®ã§ãïŒhttps://docs.google.com/presentation/d/e/${slidesId}/embed?start=false&loop=false&delayms=60000
èŠçŽãããšãGoogleã¹ã©ã€ãããŠã§ãã«å ¬éããåã蟌ãŸããiframeããidãååŸããŠããããç§ã«è¿ããªããã°ãªããªãã£ããããŠããããã©ããããèããªããã°ãªããŸããã
ãã€ãããã¯ã»ãã¬ãŒã³ããŒã·ã§ã³ã®ãµããŒã
å ã»ã©ãèšã£ãããã«ãæ°ãããã¬ãŒã³ããŒã·ã§ã³ããããã³ã«ãã®ã¢ããªãäœãçŽãããã¯ãããŸããããã èªåã®ãã¬ãŒã³ããŒã·ã§ã³IDãã¢ããªã«æž¡ããŠçµããããã®ã§ãããããã§ããã°ãåå©ã ãšæããŸãã
ç§ã¯ããã¬ãŒã³ããŒã·ã§ã³ãåçã«æ€çŽ¢ããããã«ãŠã§ãã¢ããªãæ§æããŸãããç§ã®ããŒãžæ§é ã¯ä»¥äžã®ããã«ãªããŸãïŒ
ââpages
â ââ[name]
â â ââindex.js
â â ââreact.js
â â ââresults.js
ããã«ã¯ããã€ãã®ããŒãžããããããããã«ããã€ãããã¯ããã®æã¡å³ããããŸãã
ãã¬ãŒã³ããŒã·ã§ã³ã®ããŒãž
ãã®ãã¬ãŒã³ããŒã·ã§ã³IDã¯ãŸã£ãããŠãŒã¶ãŒãã¬ã³ããªãŒã§ã¯ãããŸãããç§ã¯ããããã¬ã³ããªãŒãªååã§ãšã€ãªã¢ã¹ã«ãããã£ãã®ã§ã人ã ã¯ãã®æªç©ãå ¥åããå¿ èŠã¯ãããŸãããããã§ããããã³ã°ãè¡ãAPIãšã³ããã€ã³ããã¢ããªå ã«äœæããŸãããä»ã®ãšãããããŒãã³ãŒãããããªã¹ãã䜿ã£ãŠããŸããããã¬ãŒã³ããŒã·ã§ã³ã®åæ°ãå¢ããã«ã€ããŠãããŒã¿ããŒã¹ã«è©³çŽ°ãä¿åããŠæŽæ°ãããã¬ãŒã³ããŒã·ã§ã³ç®¡çããŒãžã«ç§»è¡ããã€ããã§ãã
import slides from '../../../lib/slides';
export default async function handler(req, res) {
try {
const { name } = req.query;
const presentation = slides.find(m => m.name == name.toLowerCase());
if (!presentation) {
return res.status(404).json({ message: `A presentation with the name "${name}" could not be found.` });
}
return res.status(200).json({ id: presentation.id, title: presentation.title });
} catch (err) {
console.error(err);
res.status(500).json({ message: 'Something went wrong' });
}
};
slidesã®ã€ã³ããŒãã¯ãGoogle Slidesã®idãã¿ã€ãã«ããã¬ãŒã³ããŒã·ã§ã³ã®ãã¬ã³ããªãŒåãæã€jsoné åã ãã§ãïŒ
const slides = [
{
name: 'caching-use-cases',
id: '2PACX-1vQxQnmKrdy1FX3KzTWs7mC89UHDNH5kVeiUJpeZBnQiWNYXX6QjupaUln',
title: 'You DO Have A Use Case For Caching'
},
{
name: 'building-a-serverless-cache',
id: '2PACX-1vSmwWzT1uMNfXpfwujfHFyOCrFjKbL8X43sd5xOpAmlK01lEICEm2kg',
title: 'Behind the Scenes: Building a Serverless Caching Service'
}
];
誰ããç§ã®ã¢ããªã®/caching-use-casesãšã³ããã€ã³ããããããããšãããŒãžã¯ãµãŒããŒåŽã®ã³ã³ããŒãã³ãããGoogleã¹ã©ã€ãã®IDãšã¿ã€ãã«ãååŸããããã䜿ã£ãŠiframeå ã®ã³ã³ãã³ããã¬ã³ããªã³ã°ããŸãã
Reaction page
ç§ã¯ãã€ã±ã«ã®ããã«ãªããããšé¡ããŸããããã®ããã«ãç§ããã¬ãŒã³ãããŠããæäžã«ã人ã ãç§ã®ãã¬ãŒã³ã«ãªã¢ã¯ã·ã§ã³ã§ãããããªãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããå¿ èŠããããŸãããããã§ã/[name]/reactãã¹ã掻èºããŸãã
ãŸãããã®ããŒãžã«äººãéããªããã°ãªããŸããã§ãããããããããŒãã³ãŒãã£ã³ã°ã¯ããããªãã£ãã®ã§ãã幞éãªããšã«ãReactã¢ããªã§QRã³ãŒããåçã«äœæããŠã¬ã³ããªã³ã°ããŠãããreact-qr-codeã©ã€ãã©ãªãå¶ç¶èŠã€ããŸãããããã§ããã¬ãŒã³ããŒã·ã§ã³ã»ãã£ã¹ãã¬ã€ã®äžã«åžžã«è¡šç€ºãããã«ãŒããè¿œå ãããŠãŒã¶ãŒãæºåž¯é»è©±ã§ã¹ãã£ã³ããŠçŽæ¥ãªã¢ã¯ã·ã§ã³ã«ãžã£ã³ãã§ããããã«ããŸããã
念ã®ããã«èšã£ãŠãããšããã®ãããžã§ã¯ãã§ã¯Amplify UIã³ã³ããŒãã³ãã䜿çšããŠããŸããç§ã¯UIã«ã¯ããŸã詳ãããªãã®ã§ããã®ãããªã¹ã¿ã€ã«ä»ãã³ã³ããŒãã³ãããããšå©ãããŸãïŒãšã«ããããã¬ãŒã³ããŒã·ã§ã³ã®äžã«ã«ãŒããè¿œå ãããšããã®ããã«ãªããŸãïŒ
ããã¯ãã¬ãŒã³ããŒã·ã§ã³ã®éãã£ãšè¡šç€ºãããã®ã§ã芳客ãæ©ãæ¥ãŠãé ãæ¥ãŠãé¢ä¿ãªãããªã¢ã¯ã·ã§ã³ããŒãžã«ã¢ã¯ã»ã¹ããŠçµµæåãéã£ãã質åããããããããšãã§ããŸãããªã¢ã¯ã·ã§ã³ããŒãžã¯ã¢ãã€ã«ã§ã®é²èŠ§ã«æé©åãããŠãããèŽè¡ã¯3ã€ã®çµµæåãéžã¶ããèªåã®è³ªåãã³ã¡ã³ããè¿œå ããããšãã§ããŸãã
èŽè¡ãçµµæåãæŒãããã質åãå ¥åããããããšãç§ãã¡ã®ç®¡çããWebSocketïŒè©³çŽ°ã¯åŸã»ã©ïŒãä»ããŠãã¬ãŒã³ããŒã·ã§ã³ã»ããŒãžã«ã¡ãã»ãŒãžãéä¿¡ãããã¹ã¯ãªãŒã³ã«è¡šç€ºãããŸããå¿é ãç¡çšãé¿ããããªã眵声ã®ããã«ãã³ã¡ã³ãã®ã¹ããããªã³ã°ãšåæ¶çãªãã£ã«ã¿ãŒãçµã¿èŸŒãã§ãããŸãã
å°èŠæš¡å±éâ
ãã®ãããžã§ã¯ãã®ããã²ãšã€ã®ç®çã¯ã倧èŠæš¡ãªããã¯ã»ã¢ãŒããã¯ãã£ã«äŸåãããèªå·±å®çµåã®å°ããªãŠã§ãã»ã¢ããªãäœãããšã§ãããããã¯ã·ã³ãã«ã§ããããšãæå³ããŠããŸããWebSocketãããã£ãããAWSã®ã³ã³ãœãŒã«ã§ããããã®ã¯ã©ãŠããªãœãŒã¹ãäœã£ããããããããŸããã§ããããã®ä»£ããã«ãç§ã¯Momentoãå©çšããããšã«ããŸããã
ãã¹ãŠã¯Next.jsã¢ããªã§èªå·±å®çµããŠããŸãããã¬ã³ããªãŒåãšãã¬ãŒã³ããŒã·ã§ã³IDã®ãããã³ã°ã¯ã¢ããªã®ãµãŒããŒåŽã³ã³ããŒãã³ãã§è¡ãããWebSocketã¯Momento Topicsãä»ããŠåŠçãããŸããWebSocketãã£ã³ãã«/ãããã¯ããµãã¹ã¯ãªãã·ã§ã³ã®ãããªã¯ã©ãŠããªãœãŒã¹ã管çããå¿ èŠã¯ãããŸãããMomento Web SDKããã©ã°ã€ã³ããã°ãããšã¯åãã ãã ãæåéãã§ãã
ã¯ã©ãŠãã§ãããå©çšããããã«ããªããã°ãªããªãã®ã¯ããŠã§ããã¹ãã£ã³ã°ã®ã»ããã¢ããã ãã§ããç¹å®ã®ã¯ã©ãŠãã»ãã³ããŒã«äŸåããããã§ã¯ãªãã®ã§ãVercelãFastlyããããã¯AWS Amplifyã®ãããªãã®ïŒç§ã®å人çãªå¥œã¿ïŒã§ãã¹ãããããšãã§ããŸããããããã»ããã¢ããããåã«ããŸããããªããã°ãªããªãããšã2ã€ãããŸãïŒ
1.ãã¬ãŒã³ããŒã·ã§ã³ã§/lib/slides.jsãã¡ã€ã«ãæŽæ°ãã
2.3ã€ã®ç°å¢å€æ°ãèšå®ãã
ã»MOMENTO_AUTH
â Momento ã³ã³ãœãŒã«çµç±ã§çºè¡ããã API ããŒããã®ããŒã¯ã³ã¯ããµãŒããŒåŽã®ã³ã³ããŒãã³ãããã©ãŠã¶ã®ã»ãã·ã§ã³ã«éä¿¡ãããçåœã® API ããŒã¯ã³ãèšå®ããããã«äœ¿çšãããŸãã
ã»NEXT_PUBLIC_CACHE_NAME
â Momento ã§äœ¿çšãããã£ãã·ã¥ã®ååãAPIããŒãšåããªãŒãžã§ã³ã«ååšããå¿
èŠããããŸããã¢ããªããã¹ãŠãã£ãŠãããã®ã§ã奜ããªååã§ãã£ãã·ã¥ãäœæããã°åé¡ãããŸããã
ã»NEXT_PUBLIC_DOMAIN_NAME
â ã¢ããªã®ã«ã¹ã¿ã ãã¡ã€ã³ã®ããŒã¹URLãã«ã¹ã¿ã ãã¡ã€ã³ã§ããå¿
èŠã¯ãªãããããã€åŸã«çæããããã¡ã€ã³ã«æŽæ°ããããšãã§ããŸãã
ãããããããã€ãå®è¡ããŸãïŒäžåºŠãããã€ããã°ãããšã¯åãåºãã ãã§ãã
楜ããçµ±èš
ãã¬ãŒã³ã®æåŸã«æ¥œããçµ±èšãèŠããããšããç§ã®èŠæ±ã®ã²ãšã€ã ãšèšãããŸããã誰ãäžçªåå¿ããããäžçªäœ¿ããããªã¢ã¯ã·ã§ã³ã¯äœããèŠãããšä»¥äžã«æ¥œããããšãããã§ããããïŒâ
誰ãããªã¢ã¯ã·ã§ã³ã»ãã¿ã³ãæŒããã³ã«ããªã¢ã¯ã·ã§ã³ããã人ãšãªã¢ã¯ã·ã§ã³ããã人ã®äž¡æ¹ã«åŸç¹ãå ç®ãããŸãã
await cacheClientRef.current.sortedSetIncrementScore(process.env.NEXT_PUBLIC_CACHE_NAME, `${name}-reacters`, data.username);
await cacheClientRef.current.sortedSetIncrementScore(process.env.NEXT_PUBLIC_CACHE_NAME, name, data.reaction);
ãœãŒããããã»ããã䜿ãããšã§ãç§ã¯é£ããäœæ¥ãããããšãªããªãŒããŒããŒããæ§ç¯ããŠããŸããç¹å®ã®ãŠãŒã¶ãŒåãšç¹å®ã®ãªã¢ã¯ã·ã§ã³ã®ã¹ã³ã¢ããã£ãã·ã¥ã§ã€ã³ã¯ãªã¡ã³ãããŠããŸãããã¬ãŒã³ããŒã·ã§ã³ãçµãã£ãŠçµæãèŠããšãã«ã¯ãéé ã§ã¹ã³ã¢ããã§ããããããšã§ãèªåçã«ãªãŒããŒããŒãå¹æãåŸãããšãã§ããŸãã
const getLeaderboard = async (cacheClient, leaderboardName) => {
let board;
const leaderboardResponse = await cacheClient.sortedSetFetchByRank(process.env.NEXT_PUBLIC_CACHE_NAME, leaderboardName, { startRank: 0, order: 'DESC' });
if (leaderboardResponse instanceof CacheSortedSetFetch.Hit) {
const results = leaderboardResponse.valueArrayStringElements();
if (results.length) {
board = results.map((result, index) => {
return {
rank: index + 1,
username: result.value,
score: result.score
};
});
}
}
return board;
};
ãªãŒããŒããŒãã®çµæã¯ãããŒã¿ãä¿åããããŒãšããŠãã¬ãŒã³ããŒã·ã§ã³ã®ãã¬ã³ããªãŒããŒã ã䜿çšããåçã§ããããšãããããŸãããã®çµæãããŒãžã¯ãã®ããã«ãªããŸãïŒ
ããã¯ãã¬ãŒã³ããŒã·ã§ã³ã«ã¡ãã£ãšãã競äºãšæ¥œãã¿ããããããèŽè¡ãååã«æ¹ãã€ããŠããããšãæåŸ ãããã®ã§ããã
èªåã§ãã£ãŠã¿ã
ãã²è©ŠããŠã¿ãŠãã ãããèŽè¡ãå·»ã蟌ãã§ãããªãã®ãã¬ãŒã³ããŒã·ã§ã³ãéç«ãããŸãããã
ãããããããã ãããšæã£ãŠããããçãã¯ãããããŸãããïŒ
Vercelã®ãããªãã¹ãã£ã³ã°ã»ãã©ãããã©ãŒã ã§ã¯ã趣å³ã®ãããžã§ã¯ãããã¹ãããã®ã«è²»çšã¯ããããŸãããMomentoã¯ããŒã¿è»¢éé1GBããã0.50ãã«ã§ãæ¯æ5GBãç¡æã§ããåãªã¢ã¯ã·ã§ã³ã¯80ãã€ãã®ã¡ãã»ãŒãžãéä¿¡ããã®ã§ãç¡æã§å©çšã§ãããªã¢ã¯ã·ã§ã³ã®éã¯æ¬¡ã®ããã«èšç®ã§ããŸãïŒ
5 GB / (80 bytes x 2 (data in from publisher and out to subscriber)) = 33.5 million
ã€ãŸãã1ã¶æã®ãªã¢ã¯ã·ã§ã³æ°ã3,350äžä»¥äžã«æããã°ãç¡æãã£ã¢ã®ç¯å²å ã§ã ð ãããããããè¶ ããå Žåã¯ã1ãã«ã§1300äžãªã¢ã¯ã·ã§ã³ãåŸãããšãã§ããŸãã
çµå±ã®ãšããããŽãŒã«ã¯äººã ãããªãã®ã¡ãã»ãŒãžãç解ããèŠããŠãããããšã§ãããªã¢ã¯ã·ã§ã³ãå€ããããã³ã¡ã³ããå¢ãããããåãé€ããããããªãã®ã³ã³ãã³ãã«æ³šæãåãç¶ãããããããªããšãªãäœã§ãèªç±ã«ãã£ãŠãã ããã
ãããäœãã€ã³ã¹ãã¬ãŒã·ã§ã³ãäžããŠããããã€ã±ã«ã»ãªãšã³ãã«æè¬ããŸãããšãŠã楜ããããå°æ¥çãªæ¡åŒµã®å¯èœæ§ããããããããŸããé åçãªãã¬ãŒã³ããŒã·ã§ã³ãæäŸãããªã¢ã«ã¿ã€ã ã§èŽè¡ã®ãã£ãŒãããã¯ãåŸãããããšã«è奮ããŠããŸãã
ãããã€ãMomentoããŒã¯ã³ã®ååŸããã¬ãŒã³ããŒã·ã§ã³ã®å ¬éæ¹æ³ãªã©ããã€ã§ããæäŒãããŸããç§ãMomentoããŒã ã®èª°ããDiscordãMomentoã®ãŠã§ããµã€ãããé£çµ¡ããŸãã
Happy coding!