<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Websockets &#8211; Few Steps &#8211; ก้าวสั้นๆ แต่ไปเรื่อยๆ</title>
	<atom:link href="https://myifew.com/tag/websockets/feed/" rel="self" type="application/rss+xml" />
	<link>https://myifew.com</link>
	<description></description>
	<lastBuildDate>Fri, 07 Jun 2019 03:10:31 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://myifew.com/wp-content/uploads/2018/07/cropped-logo6-ts-32x32.png</url>
	<title>Websockets &#8211; Few Steps &#8211; ก้าวสั้นๆ แต่ไปเรื่อยๆ</title>
	<link>https://myifew.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>ลองทำ Serverless WebSocket ด้วย AWS Lambda และ AWS API Gateway</title>
		<link>https://myifew.com/5321/real-time-applications-with-serverless-websockets-by-aws-lambda-and-api-gateway/</link>
					<comments>https://myifew.com/5321/real-time-applications-with-serverless-websockets-by-aws-lambda-and-api-gateway/#respond</comments>
		
		<dc:creator><![CDATA[iFew]]></dc:creator>
		<pubDate>Wed, 27 Mar 2019 03:20:18 +0000</pubDate>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[API Gateway]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[AWS Lambda]]></category>
		<category><![CDATA[Microservices]]></category>
		<category><![CDATA[Serverless]]></category>
		<category><![CDATA[Websockets]]></category>
		<guid isPermaLink="false">https://myifew.com/?p=5321</guid>

					<description><![CDATA[แนวคิดการทำ WebSocket ด้วย Serverless ที่มันดูค่อนข้างขัดแย้งกัน แต่มันก็ทำได้นะ ด้วย AWS Lambda และ AWS API Gateway]]></description>
										<content:encoded><![CDATA[
<p>อยากอัพเดทข้อมูลแบบ Real-time, แสดงข้อความ Notification ทันทีเมื่อมีการแจ้งข่าวให้สมาชิก, ทำระบบแชทที่พูดคุยกันได้ตลอดเวลา ฯลฯ ระบบแบบนี้เรามักทำเป็น WebSocket ซึ่งเป็น Protocol หนึ่งที่จะเปิดท่อ Connection ไว้เพื่อให้สื่อสารระหว่าง Server  และ Client ได้ตลอดเวลา ซึ่งรายละเอียดมากกว่านี้ หรือทำอย่างไร ลองไปหาจาก Google ได้เยอะแยะ</p>



<p>แต่ที่ชวนฉงนคือ การทำงานของ Serverless เป็นแบบ เกิดขึ้น และทำ Process แล้วก็ดับไป มันจะทำเป็น WebSocket  ได้ด้วยหรอ เพราะต้องเปิดแช่ Connection เพื่อสื่อสารกันตลอดเวลา </p>



<p>โพสต์นี้จะแชร์แนวคิดให้อ่านกัน ว่ามันเป็นไปได้จริงๆ ด้วยบริการของ Amazon API Gateway และ AWS Lambda ส่วนโค้ดตัวอย่าง ไปดูได้ที่ Github (<a href="https://github.com/ifew/aws-lambda-websocket">aws-lambda-websocket</a>) ผมได้เลย</p>



<span id="more-5321"></span>



<h2 class="wp-block-heading">อธิบายการทำงาน</h2>



<p>การทำ Websocket ด้วย Lambda มีจุดสำคัญอยู่ 2 จุด คือ </p>



<h4 class="wp-block-heading"><strong>1.Amazon API Gateway</strong> </h4>



<p>ซึ่งทาง Amazon เอง เพิ่งประกาศฟีเจอร์ WebSocket นี้เมื่อ 3 เดือนที่แล้วนี่เอง (<a rel="noreferrer noopener" aria-label="18 ธันวาคม 2561 (opens in a new tab)" href="https://aws.amazon.com/th/blogs/compute/announcing-websocket-apis-in-amazon-api-gateway/" target="_blank">18 ธันวาคม 2561</a>) โดยสามารถใช้งานกับบริการต่างๆของ Amazon ได้ เช่น AWS Lambda, Amazon Kinesis, หรืออื่นๆที่เชื่อมต่อด้วย HTTP endpoint </p>



<figure class="wp-block-image"><img fetchpriority="high" decoding="async" width="928" height="571" src="https://myifew.com/wp-content/uploads/2019/03/api-gw-create-websockets.png" alt="" class="wp-image-5323"/><figcaption>หน้าตาของ Amazon API Gateway ตอนที่จะสร้าง WebSocket API</figcaption></figure>



<p>ซึ่งใน Amazon API Gateway ส่วนของ Websocket API จะมีการ Config Resource Type ต่างจากแบบ REST คือ </p>



<ol class="wp-block-list"><li><strong>route</strong> ที่เอาไว้เป็นช่องทางจัดการคำขอต่างๆที่มาจากผู้เรียกใช้ (route selection expression)</li><li><strong>routeKey</strong> ที่เป็นช่องทางของคำขอ โดยแบ่งได้ 3 routeKey หลัก คือ<ul><li><strong>$default</strong> &#8211; ใช้สำหรับคำขอที่ไม่เข้าเงื่อนไขใดๆเลย จากผู้รองขอ เช่น การส่งข้อมูล Error ให้กับผู้ร้องขอ</li><li><strong>$connect</strong> &#8211; ใช้สำหรับเมื่อมีผู้ร้องขอเพื่อขอใช้งาน และตรวจพบว่าเป็นการเรียกใช้ Websockets นี้ครั้งแรก (การที่เคยขอใช้ และ Connection ของ WebSocket หมดอายุไป ก็ต้องเรียก Connect ใหม่เช่นกัน)</li><li><strong>$disconnect</strong> &#8211; ใช้สำหรับบอกว่าผู้ใช้งานมีการ Disconnect จาก API ไปแล้ว ก็จะทำการตัด Connection ของ WebSocket ออกไปด้วย</li></ul></li></ol>



<figure class="wp-block-image"><img decoding="async" width="1219" height="636" src="https://myifew.com/wp-content/uploads/2019/03/api-gw-integrate-lambda.png" alt="" class="wp-image-5326"/></figure>



<h4 class="wp-block-heading"><strong>2.การเก็บ Connection ID ลง ฐานข้อมูล </strong></h4>



<p>โดยปกติถ้าเราเขียน WebSocket ทั่วไป มันจะทำการเก็บ Connection ID ไว้ใน Server แต่เมื่อเราทำบน Serverless อย่าง AWS Lambda ที่ธรรรมชาติของมันพร้อมจะปิดสวิตส์ตัวเองเสมอเมือ่ไม่ได้ใช้งานนานๆ เราจึงต้องเพิ่มการเก็บ Connection ID ลงในฐานข้อมูลแทน เพื่ออ้างอิงไว้ใช้ เมื่อ Lambda เราตื่นขึ้นมาทำงานต่อ</p>



<h2 class="wp-block-heading">ตัวอย่างการทำงาน AWS Lambda กับ WebSocket </h2>



<figure class="wp-block-image"><img decoding="async" width="747" height="429" src="https://myifew.com/wp-content/uploads/2019/03/websockets-arch.png" alt="" class="wp-image-5325"/><figcaption>รูปจาก https://aws.amazon.com/th/blogs/compute/announcing-websocket-apis-in-amazon-api-gateway/</figcaption></figure>



<p>ในรูปตัวอย่าง อธิบายการทำงานของระบบ Chat ที่ใช้ Lambda และ WebSocket API โดยมีขั้นตอนคือ</p>



<ul class="wp-block-list"><li>ผู้ใช้ เข้ามาใช้งาน Chat Room ซึ่งระบบก็จะทำการ connect ไปที่ WebSocket API </li><li>ระบบ WebSocket API จะทำการสร้าง Connection ID และส่ง message กลับไปหาผู้ร้องขอตาม URL ที่มีการเรียกใช้มาตอนแรก (URL Callback) เพื่อบอกว่า  ทำการเชื่อมต่อสำเร็จ (Connected) พร้อมทั้งเก็บ Connection ID ไว้ในฐานข้อมูลด้วย</li><li>เมื่อผู้ใช้ส่งข้อความ Chat ไปให้ WebSocket API มันจะส่ง message นั้นไปที่ Reosource ที่เรากำหนดไว้ (ซึ่งในที่นี้คือ Lambda Function สำหรับการ Chat) โดยไม่ต้อง connect ใหม่อีกรอบ</li><li>message ที่ถูกส่งมา จะถูกกระจายส่งไปหา Connection ทุกคนที่มี Connection ID อยู่ในรายการฐานข้อมูล</li><li>สุดท้าย เมื่อพบว่าผู้ใช้ออกจากห้อง Chat Room ไปแล้ว ตัว WebSocket API จะ Disconnect ผู้ใช้คนนั้นอัตโนมัติ</li></ul>



<p>ผมทดลองโดยเปิด Connection ไว้ สามหน้าต่าง ซึ่งจะมี Connection ID ต่างกัน ดังนั้น เมื่อผมส่ง message ออกจากหน้าต่างไหนก็ตาม มันจะถูกเผยแพร่ไปหาหน้าต่างอื่นๆ ด้วย ดังนั้น จึงเหมาะกับงานประเภททำงานแบบ Realtime และ Broadcast เช่น Chat, Notification, Bidding หรือแม้แต่ระบบโหวตและนับคะแนนเสียงเลือกตั้ง </p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="2716" height="1648" src="https://myifew.com/wp-content/uploads/2019/03/Screen-Shot-2562-03-27-at-09.48.57.png" alt="" class="wp-image-5331"/><figcaption>ตัวอย่างการทำงานเพื่อคุยข้าม Connection กัน<br></figcaption></figure>



<p>ตัวอย่างโค้ด ดาวน์โหลดได้ที่ <a href="https://github.com/ifew/aws-lambda-websocket">https://github.com/ifew/aws-lambda-websocket</a></p>



<h2 class="wp-block-heading">ค่าใช้จ่าย สำหรับ AWS Lambda WebSocket </h2>



<p>ค่าใช้จ่ายในส่วนของ AWS Lambda จะเหมือนเดิม ตามที่เคยเขียนเล่าไว้ในบล็อก <a href="https://myifew.com/5166/understand-serverless-with-aws-lambda-for-newbie/">มาทำความรู้จักกับ Serverless และ AWS Lambda ฉบับคนคิดจะใช้</a> </p>



<p>จะมีที่แตกต่างคือการคิดเงินในฝั่งของ Amazon API Gateway ที่คิดตาม request และ จำนวนนาทีที่มีการเชื่อมต่ออยู่ สามารถดูได้จากตารางด้านล่าง</p>



<figure class="wp-block-image"><img loading="lazy" decoding="async" width="881" height="511" src="https://myifew.com/wp-content/uploads/2019/03/websockets-pricing.png" alt="" class="wp-image-5327"/></figure>



<p>ถามว่าแพงไหม ผมก็ไม่รู้นะ อยู่ที่การใช้งานของแต่ละระบบ แต่จำนวน request 1พันล้านแรก ราคา $1.15 กับ connection 1 ล้านนาที ราคา $0.288 คงเป็นตัวเลขที่ถูกแสนถูก มากๆ เท่ากับข้าวแกงจานนึง </p>



<p>แต่ตัวแปรสำคัญคงอยู่ที่ Lambda Compute ที่อาจจะแพง ฮ่าๆ เพราะ การทำงาน 1 ชุด จะมี Lambda อย่างน้อย 3 ตัวแน่นอน คือ Connect, Disconnect, Default ส่วน Lambda จะมีค่าใช้จ่ายสูงแค่ไหน ก็กลับไปดูจำนวน request และ compute time (วิธีคิดอ่านได้จากบล็อก <a href="https://myifew.com/5166/understand-serverless-with-aws-lambda-for-newbie/">มาทำความรู้จักกับ Serverless และ AWS Lambda ฉบับคนคิดจะใช้</a> )</p>



<h2 class="wp-block-heading">ข้อจำกัด</h2>



<ul class="wp-block-list"><li>รองรับผู้ใช้งานได้ 10,000 requests ต่อวินาที (RPS) ต่อ region (สามารถขอเพิ่มจากทาง Amazon ได้)</li><li>ระบบจะทำการเพิ่มให้ 500 requests ในทุกๆวินาที ต่อ region</li><li>ส่งข้อมูลผ่าน WebSocket (frame size) ได้ไม่เกิน 32 KB ถ้าต้องใช้มากกว่านั้น ต้องตัดข้อมูลเป็นเฟรมๆเพื่อส่ง, ซึ่งถ้าส่งเกิน ระบบจะทำการ Disconnect อัตโนมัติ</li><li>ระยะเวลาสำหรับ Connection อยู่ได้ 2 ชั่วโมง</li><li>เข้าสู่โหมด Idle Connection Timeout ที่เวลา 10 นาที กรณีไม่มีการส่งข้อมูลอะไรผ่าน WebSocket API</li><li>สามารถทำ AWS Lambda authorizers ต่อ API ได้ 10 ตัว (สามารถขอเพิ่มจากทาง Amazon ได้)</li><li>สร้าง Routes ต่อ API ได้ไม่เกิน 300 ตัว (สามารถขอเพิ่มจากทาง Amazon ได้) </li><li>ทำการเชื่อมต่อ API กับ Resource ต่างๆ เช่น AWS Lambda (Integrations) ได้ไม่เกิน 300 ตัว (สามารถขอเพิ่มจากทาง Amazon ได้)</li><li>สามารถมี Stages ต่อ API ได้ไม่เกิน 10 ตัว (สามารถขอเพิ่มจากทาง Amazon ได้)</li></ul>



<h2 class="wp-block-heading">สรุป</h2>



<p>น่าสนใจมากๆ สำหรับการทำ WebSocket ด้วย Serverless ดูเป็นเรื่องน่าสนุกดีสำหรับผม  เหมือนได้เล่นของใหม่ ที่พยายามพลิกแพลง Serverless มาทำ แต่ถามว่าดีหรือไม่ เหมาะสมไหม ตอนนี้มันยังใหม่มาก หาเคสตัวอย่างใหญ่ๆ ไม่เจอ (หรืออาจจะมีแต่ไม่มีใครเปิดเผย) ดังนั้นถ้าให้บอกข้อดีที่นึกออกตอนนี้ ก็คงเรื่องของราคาค่า Server ที่มันถูกลง ตาม benefit เดิมของ Serverless นั่นแหละ, ส่วนข้อเสียที่ผมพบตอนนี้ รู้สึกทดสอบยาก ณ ตอนเขียนบล็อกนี้ยังนึกการทำ Integration Test ไม่ออกเลย นอกจากการ Deploy ขึ้นไปทดสอบบน AWS เอง, หากใครคิดออก หรือมีตัวอย่างเจ๋งๆ ก็แชร์กันได้นะครับ</p>



<p><strong>อ้างอิง</strong></p>



<ul class="wp-block-list"><li><a href="https://aws.amazon.com/th/blogs/compute/announcing-websocket-apis-in-amazon-api-gateway/">https://aws.amazon.com/th/blogs/compute/announcing-websocket-apis-in-amazon-api-gateway/</a></li><li>รูปปกจาก <a href="https://blog.stanko.io/do-you-really-need-websockets-343aed40aa9b?gi=77181225da63">https://blog.stanko.io/do-you-really-need-websockets-343aed40aa9b?gi=77181225da63</a></li></ul>
]]></content:encoded>
					
					<wfw:commentRss>https://myifew.com/5321/real-time-applications-with-serverless-websockets-by-aws-lambda-and-api-gateway/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
