HTTP ย่อมาจาก HyperText Transfer Protocol เป็นโปรโตคอลที่ใช้งานในด้านเว็บไซต์และในระบบอินเตอร์เน็ต ในปัจจุบันเมื่อต้องการให้อุปกรณ์ต่าง ๆ สามารถสื่อสารกับข้ามแพลตฟอร์ม มักจะนิยมใช้งาน HTTP เนื่องจากเป็นโปรโตคอลมาตรฐานที่มีมาให้ใช้งานในทุกภาษา และทุกอุปกรณ์ที่เชื่อมต่ออินเตอร์เน็ตได้ พื้นฐานของ HTTP มาจากโปรโตคอล TCP ที่มีการใช้เพื่อรับ – ส่งข้อมูลในรูปแบบตามมาตรฐาน และใช้พอร์ต 80 เป็นค่าเริ่มต้น กรณีใช้งานพอร์ตอื่นต้องระบุพอร์ตลงในลิ้งหรือ URL ด้วย
ก่อนเลย เราต้องมาทำความเข้าพื้นฐานการทำงานของเว็บไซต์กันก่อน ทันทีที่มีการพิมพ์ชื่อเว็บไซต์ลงในเว็บเบราว์เซอร์และกดปุ่ม Enter จะมีขบวนการต่าง ๆ ตามแผนผังดังนี้
จากแผนผังจะเห็นไว้ว่า เมื่อมีการพิมพ์ชื่อเว็บไซต์ต่าง ๆ ลงไป ชื่อเว็บไซต์เหล่านั้นจะถูกแปลงเป็นหมายเลข IP เสียก่อน โดยขบวนการแปลงนี้จะกระทำผ่านบริการแปลงชื่อโดเมนไปเป็นหมายเลข IP หรือ DNS หลังจากได้หมายเลข IP มาแล้ว จึงจะเริ่มการรับ – ส่งข้อมูลกับเซิร์ฟเวอร์ได้ แต่หากมีการพิมพ์หมายเลข IP ลงไปตรง ๆ กระบวนการจะลัดไปที่การเชื่อมต่อกับเซิร์ฟเวอร์ปลายทางเลย
กระบวนการดังที่กล่าวมานี้ เป็นกระบวนการทำงานของ HTTP Client ซึ่งใช้เพื่อส่งข้อมูลไปหาเครื่องเซิร์ฟเวอร์เพื่อให้โปรแกรมสามารถทำงานได้ตามที่ต้องการ เช่น ใช้ HTTP Client ส่งข้อมูลไปที่เซิร์ฟเวอร์ของ Facebook เพื่อให้โพสข้อความ หรือใช้เพื่อส่งข้อมูลไปเก็บไว้ เป็นต้น
สำหรับฝั่งของเซิร์ฟเวอร์จะเรียกว่า HTTP Server การใช้ HTTP Server จะใช้ต่อเมื่อต้องการให้ ESP32 สามารถให้บริการได้ เช่น การสั่งเปิด-ปิดกลอนประตู การให้ข้อมูลของอุณหภูมิ โดย HTTP Server จะทำหน้าที่รอการเชื่อมต่อและร้องขอข้อมูลที่ต้องการ แล้วจึงเริ่มส่งข้อมูลให้
ดังนั้นการทำงานโดยรวมของโปรโตคอล HTTP คือการให้ฝั่ง Client เริ่มส่งข้อมูลที่ต้องการก่อน แล้วฝั่ง Server จะส่งข้อมูลที่มีกลับไป
ในการใช้งานกับ ESP32 เราไม่จำเป็นต้องทราบหลักการทำงานทั้งหมดของโปรโตคอล HTTP เนื่องจาก ESP32 มีไลบารี่มาให้ใช้งานพร้อมอยู่แล้ว จึงสามารถใช้งานได้โดยง่ายเพียงเรียกฟังก์ชั่นที่ต้องการใช้งานก็สามารถใช้ HTTP Client และ HTTP Server ได้เลย
ในการเข้าเว็บไซต์เพื่อเรียกข้อมูล หรือขอข้อมูลไปที่เซิร์ฟเวอร์ จะมีองค์ประกอบของข้อมูลที่ส่งไปให้ ดังนี้
เป็นส่วนประกอบหลักที่จะกำหนดว่าเซิร์ฟเวอร์จะตอบข้อมูลชุดใดกลับไป เนื่องจากภายในเซิร์ฟเวอร์ 1 ตัว สามารถบรรจุเว็บไซต์ได้หลายเว็บ และตัวซอฟแวร์ HTTP Server สามารถแยกข้อมูลของแต่ละเว็บออกจากกันได้จากชื่อโดเมน ชื่อโดเมนคือส่วนแรกสุดของลิ้งหรือ URL เมื่อนำลิ้งหนึ่งมาพิจารณาจะได้ส่วนของโดเมนดังนี้
เส้นทาง คือที่อยู่ของข้อมูลที่ต้องการเรียกใช้งาน แบบเดียวกับบนคอมพิวเตอร์ของเราที่จะเรียกที่อยู่ของไฟล์ด้วยเส้นทาง เช่น ไฟล์งานอยู่ในไดร์ D โฟลเดอร์ที่ชื่อ Work และไฟล์ชื่อ Work1Day.docs เมื่อเข้าไปตามข้อความข้างต้น ที่ช่องแสดงเส้นทางด้านบนจะแสดงว่า D:\Work\Work1Day.docs เช่นเดียวกับบนเว็บไซต์ หากไฟล์งานอยู่ในโฟลเดอร์ที่ชื่อ Work และไฟล์ชื่อ Work1Day.docs จะต้องเข้าไปในเส้นทาง http://youdomain/Work/Work1Day.docs จึงจะสามารถเข้าไปเรียกข้อมูลของไฟล์งานขึ้นมาได้ เมื่อนำลิ้งหนึ่งมาพิจารณาจะได้ส่วนของเส้นทางดังนี้
คำสั่งร้องขอ คือข้อความคำสั่งที่ระบุรูปแบบการส่งข้อมูลไปให้เซิร์ฟเวอร์ มีคำสั่งที่นิยมใช้งานอยู่ 2 คำสั่ง คือ
คำสั่งร้องขอแบบ GET เราสามารถเห็นข้อมูลที่ส่งไปได้โดยพิจารณาจากลิ้ง หรือ URL ดังตัวอย่างลิ้งนี้
สั่งเกตว่าชุดข้อมูลจะถูกแยกออกจากเส้นทางด้วยเครื่องหมาย ? และจะถูกแยกระหว่างข้อมูลด้วยเครื่องหมาย & กรณีข้อมูลที่ส่งมีชุดเดียวจะไม่มีเครื่องหมาย &
การส่งข้อมูลทั้งแบบ GET และแบบ POST ข้อมูลที่เป็นอักษรพิเศษ หรือเป็นภาษาไทย จะต้องถูกแปลงเป็นชุดข้อความที่ถูกเข้ารหัสแล้ว โดยข้อมูลที่ส่งผ่านคำสั่งแล้วใช้การเข้ารหัสมักเรียกว่า url encode ดังนั้นเมื่อต้องการส่งข้อมูลภาษาไทยไปที่ลิ้ง หรือ URL ใด ๆ จะต้องแปลงข้อความนั้นก่อนทุกครั้ง ซึ่งการแปลงข้อความสามารถใช้เว็บไซต์ได้หลาย ๆ เว็บ สำหรับผู้เขียนจะขอแนะนำเว็บ https://goo.gl/SZCqbV ใช้แปลงข้อความ
หลังจากมีการเรียกขอข้อมูลไปที่เซิร์ฟเวอร์แล้ว สิ่งที่เซิร์ฟเวอร์จะตอบกลับแรกสุดคือสถานะของการร้องขอข้อมูล ซึ่งเป็นตัวเลข 3 หลัก สามารถเห็นได้บ่อยมีดังนี้
รหัสสถานะภาพนี้จะถูกนำไปใช้งานต่อเมื่อ Client มีการร้องขอข้อมูลเข้ามา แล้วต้องการตอบสถานะกลับไปพร้อมกับข้อมูลที่ต้องการส่ง และที่ Client ต้องนำรหัสสถานะภาพนี้ไปประมวลผลต่อเพื่อตรวจสอบว่าได้รับข้อมูลที่ร้องขอกลับมาหรือไม่
ฟังก์ชั่นที่ใช้งานจะแบ่งได้ 2 กลุ่ม ดังนี้
ในขณะที่ชุดบทความนี้ได้จัดทำขึ้น ไลบารี่ที่ใช้สร้าง HTTP Server ยังไม่ถูกปล่อยออกมา ทำให้ยังไม่สามารถใช้งานไลบารี่เพื่อสร้าง HTTP Server ได้โดยตรง หากมีการอัพเดทไลบารี่แล้ว จะมีการเพิ่มเนื้อหาในส่วนนี้ต่อไป
การใช้งาน HTTP Client จะต้องมีการเรียกใช้ไลบารี่ HTTPClient ทุกครั้งก่อนใช้งาน และรูปแบบของการสร้างออปเจคด้วยคลาส HTTPClient มีรูปแบบดังนี้
HTTPClient::HTTPClient()
ไม่มีค่าพารามิเตอร์
ฟังก์ชั่นที่ใช้กำหนดค่าการขอข้อมูล มีรูปแบบดังนี้
bool HTTPClient::begin(String url); หรือ bool begin(String url, const char *CAcert);
มีรายละเอียดของพารามิเตอร์ดังนี้
และมีการตอบกลับเป็นข้อมูลชนิด bool ที่จะเป็น true เมื่อลิ้งถูกรูปแบบ
ฟังก์ชั่นที่ใช้ขอข้อมูลด้วยคำสั่ง GET มีรูปแบบดังนี้
int HTTPClient::GET();
ไม่มีค่าพารามิเตอร์ และตอบกลับมาเป็นข้อมูลชนิด int ซึ่งเป็นรหัสสถานะภาพ หรือรหัสผิดพลาดในการขอข้อมูล
ฟังก์ชั่นที่ใช้ขอข้อมูลด้วยคำสั่ง POST มีรูปแบบดังนี้
int HTTPClient::POST(String payload);
มีรายละเอียดของพารามิเตอร์ดังนี้
และตอบกลับมาเป็นข้อมูลชนิด int ซึ่งเป็นรหัสสถานะภาพ หรือรหัสผิดพลาดในการขอข้อมูล
รหัสผิดพลาดในการขอข้อมูล สามารถเป็นไปได้ดังนี้
รหัส | รายละเอียดข้อผิดพลาด |
-1 | การเชื่อมต่อถูกปฏิเสธ |
-2 | การส่งส่วนหัวของ HTTP ผิดพลาด |
-3 | การส่งข้อมูลของ HTTP ผิดพลาด |
-4 | ไม่สามารถเชื่อมต่อไปยังเซิร์ฟเวอร์ปลายทางได้ |
-5 | การเชื่อมต่อถูกยกเลิกระหว่างการส่งข้อมูล |
-7 | เซิร์ฟเวอร์ปลายทางไม่ใช่ HTTP Server |
-8 | แรมไม่พอ |
-10 | ไม่ |
-11 | หมดเวลาการเชื่อมต่อก่อนข้อมูลจะถูกส่งกลับมา |
กรณีรหัสที่ตอบกลับมามีค่ามากกว่า 0 จะหมายถึงรหัสสถานะภาพ
ฟังก์ชั่นที่ใช้อ่านข้อมูลที่ได้ มีรูปแบบการใช้งานดังนี้
String HTTPClient::getString();
ไม่มีค่าพารามิเตอร์ และตอบกลับเป็นข้อมูลชนิด String ซึ่งเป็นข้อมูลที่เซิร์ฟเวอร์ส่งกลับมา
สำหรับลิ้งที่ใช้ในการทดลองคือลิ้ง http://ioxhop.info/files/test.txt เมื่อเข้าไปในหน้าเว็บจะพบข้อความว่า Hello, World! ซึ่งหากผลการทดลองถูกต้อง คำว่า Hello, World! จะถูก ESP32 ดึงมาได้
ก่อนอื่น ให้เข้าไปคัดลอกโค้ดที่ https://goo.gl/296Tzy จากนั้นแก้ไขในส่วนของ WIFI_STA_NAME และ WIFI_STA_PASS ให้ถูกต้อง แล้วอัพโหลดโค้ดลงใน NodeMCU-32S ได้เลย
จากนั้น เปิด Serial Monitor ปรับไปที่ 115200 band กดปุ่ม EN แล้วปล่อย 1 ครั้ง หลังจากเชื่อมต่อ WiFi สำเร็จแล้ว จะพบว่า ESP32 สามารถไปดึงข้อมูลจากในลิ้งที่กำหนดมาได้แล้ว
จากผลการทดลอง จะเห็นได้ว่า ESP32 เราสามารถที่จะใช้ HTTP Client ได้ง่าย ๆ เพียงใช้โค้ดไม่กี่บรรทัด ซึ่งโค้ดที่ได้ทดลองไปทั้งหมดมีดังนี้
เนื่องจากส่วนประกอบของโค้ดโปรแกรมจะมีบางส่วนที่เป็นส่วนของการเชื่อมต่อ WiFi ที่ได้เรียนรู้กันไปแล้วในบทที่ผ่านมา ดังนั้นจึงอธิบายเฉพาะส่วนที่เกี่ยวข้องกับการใช้งาน HTTP Client ได้ดังนี้
บรรทัดที่ 2 เรียกใช้ไลบารี่ HTTPClient.h เพื่อเตรียมใช้งาน HTTP Client
บรรทัดที่ 35 สร้างออปเจค http ด้วยคลาส HTTPClient เพื่อที่จะใช้งาน HTTP Client
บรรทัดที่ 36 ใช้ฟังก์ชั่นย่อย .begin() เริ่มกำหนดลิ้งที่ต้องการดึงข้อมูล
บรรทัดที่ 37 ใช้ฟังก์ชั่นย่อย .GET() ส่งคำสั่งร้องขอแบบ GET เพื่อขอข้อมูล แล้วนำผลการดึงข้อมูลไปเก็บไว้ที่ตัวแปร httpCode
บรรทัดที่ 38 ใช้คำสั่ง if ตรวจสอบโค้ดผลการดึงข้อมูลจากตัวแปร httpCode ว่าสำเร็จหรือไม่ ถ้าโค้ดที่ได้เป็น 200 จะทำคำสั่งในปีกกา
บรรทัดที่ 39 ใช้ฟังก์ชั่นย่อย .getString() อ่านข้อมูลที่ได้จากเซิร์ฟเวอร์ แล้วนำไปเก็บไว้ในตัวแปร content
บรรทัดที่ 40 ส่งข้อความไปที่ Serial Monitor
บรรทัดที่ 41 นำข้อความในตัวแปร content ส่งไปแสดงผลที่ Serial Monitor
บรรทัดที่ 42 ส่งข้อความไปที่ Serial Monitor
บรรทัดที่ 43 ถ้าเงื่อนไขใน if ที่ผ่านมาเป็นเท็จ จะทำปีกกาของ else
บรรทัดที่ 44 ส่งข้อความไปที่ Serial Monitor
บรรทัดที่ 45 จบคำสั่งใน else
บรรทัดที่ 46 ส่งข้อความไปที่ Serial Monitor
บรรทัดที่ 47 จบคำสั่งในฟังก์ชั่น setup
บรรทัดที่ 48 เริ่มและจบคำสั่งในฟังก์ชั่น loop
การส่งข้อมูลใด ๆ ก็ตามผ่าน HTTP ไปให้ฝั่งเซิร์ฟเวอร์ จะประกอบไปด้วย Key และข้อมูล เพื่อให้สามารถนำข้อมูลไปใช้งานได้สะดวกจึงได้มีการกำหนด Key และข้อมูลขึ้นมา โดย Key จะเป็นชื่อที่ตั้ง ห้ามมีตัวอักษรพิเศษ คล้าย ๆ กับการตั้งชื่อตัวแปร ที่ชื่อจะต้องสัมพันธ์กับข้อมูล การแยกข้อมูลออกจากกันจะใช้เครื่องหมาย & ในการแยก ตัวอย่างของข้อมูลของอุณหภูมิที่ต้องการส่งผ่าน HTTP ไปยังเซิร์ฟเวอร์มีดังนี้
Key | ข้อมูล | คำอธิบายข้อมูล | แปลงข้อมูล |
id | 1 | หมายเลขประจำตัวของข้อมูล | id=1&temp=30&time=12%3A50 |
temp | 30 | ค่าอุณหภูมิ | |
time | 12:50 | เวลาที่วัดอุณหภูมิ |
ทั้งนี้ชื่อ Key ที่จะส่งให้กับเซิร์ฟเวอร์จะมีการกำหนดไว้แล้ว ผู้บริการต้องทำความเข้าใจเอกสารการร้องขอข้อมูลจากเซิร์ฟเวอร์นั้น ๆ ด้วยตนเอง เนื่องจากการให้บริการเซิร์ฟเวอร์ของแต่ละที่จะมีการกำหนด Key ที่แตกต่างกัน
สำหรับการทดลองในครั้งนี้จะทดลองส่งข้อมูลข้างต้นไปยังเซิร์ฟเวอร์ปลายทางที่ให้บริการดีบัค HTTP Client โดยจะสามารถบอกได้ว่าข้อมูลที่ส่งไปยังเซิร์ฟเวอร์นั้นถูกต้องหรือไม่ รวมถึงบอกคำสั่งร้องขอที่ส่งได้ด้วย
ให้เข้าไปคัดลอกโค้ดที่ใช้ในการทดลองครั้งนี้ได้ที่ https://goo.gl/vRpzGD จากนั้นแก้ไขส่วนของ WIFI_STA_NAME และ WIFI_STA_PASS ให้ถูกต้อง แล้วอัพโหลดโค้ดลงใน NodeMCU-32S ได้เลย
ผลที่ได้ในหน้าต่าง Serial Monitor ที่ปรับเป็น 115200 band คือข้อมูลที่เซิร์ฟเวอร์ได้รับดังรูป
และโค้ดที่ได้ใช้ในการทดลองครั้งนี้มีดังนี้
จากโค้ดจะเห็นได้ว่า ได้มีการเปลี่ยนแปลงโค้ดจากตัวอย่างที่แล้วเพียงบรรทัดเดียวคือบรรทัดที่ 37 ที่เปลี่ยนจากการเรียกฟังก์ชั่นย่อย .GET() เป็นการเรียกฟังก์ชั่ยย่อย .POST() แทน และเพิ่มพารามิเตอร์ข้อมูลเข้าไป
HTTPS คือส่วนหนึ่งของโปรโตคอล HTTP โดยการเชื่อมต่อแบบ HTTPS จะสังเกตได้จากคำนำหน้าของลิ้งจะเป็น https และช่อง Address bar ของเบราว์เซอร์จะเป็นสีเขียว ซึ่งการเชื่อมต่อแบบ HTTPS จะมีการเข้ารหัสข้อมูลทั้งขาส่งและขารับ และข้อมูลจะถูกยอมรับต่อเมื่อ CA มีชื่อที่ยอมรับได้เท่านั้น
การใช้งาน HTTPS จึงต้องใช้รหัส หรือชุดข้อความหนึ่งเพื่อตรวจสอบว่าข้อมูลที่ส่งมาจากเซิร์ฟเวอร์ปลอดภัยและเป็นของจริงหรือไม่ ซึ่งรหัสที่ใช้ตรวจสอบจะแตกต่างกันแต่ละเว็บไซต์ ซึ่งสามารถหารหัสเหล่านั้นได้โดยทำตามขั้นตอนดังนี้
เข้าไปที่เว็บไซต์ที่ต้องการ จากนั้นกดปุ่ม F12 บนคีย์บอร์ด แล้วคลิกที่แท๊ป Security จากนั้นกดปุ่ม View certificate
ที่หน้าต่าง Certificate คลิปแท๊ป Details แล้วกดปุ่ม Copy to File…
ที่หน้าต่าง Certificate Export Wizard ให้กดปุ่ม Next..
ในส่วน Select the format ให้เลือก Base-64 encoded จากนั้นกดปุ่ม Next
จากนั้นกดปุ่ม Browse… เพื่อเลือกที่เก็บไฟล์ แล้วกดปุ่ม Next
จากนั้นคลิกปุ่ม Finish เป็นอันจบ
เมื่อเข้าไปดูในโฟลเดอร์ที่เลือกไว้ จะพบไฟล์แล้ว
เข้าไปในหน้าเว็บที่ต้องการ จากนั้นกดที่รูปกุญแจสีเขียว แล้วกดปุ่ม >
จากนั้นกดปุ่ม ข้อมูลเพิ่มเติม
จากนั้นกดปุ่ม ดูใบรับรอง
กดปุ่ม ส่งออก ที่อยู่ด้านล่าง
เลือกที่เก็บไฟล์แล้วกด Save ได้เลย เมื่อเข้าไปดูในโฟลเดอร์ที่เลือกเก็บจะพบไฟล์ที่ได้แล้ว
หลังจากได้ไฟล์ CA มาแล้ว ให้เปิดไฟล์ด้วยโปรแกรม Text Editor ตัวอย่างนี้จะใช้โปรแกรม Notepad++
จากนั้นข้อมูลในไฟล์ทั้งไปแปลงในเว็บไซต์ https://goo.gl/pU4s0e โดยใส่ข้อมูลลงในช่อง Source text แล้วกดปุ่ม Convert จะได้ข้อความในช่อง C/C++ string ที่ใช้ใส่ในโปรแกรม Arduino
เมื่อในไปใส่ในโปรแกรม Arduino จะต้องมีการประกาศตัวแปรเพื่อเก็บข้อความไว้ด้านบน
ในแต่ละบรรทัดเติม \ ไปด้านหลัง เพื่อบอกว่าเป็นข้อความที่อยู่ในตัวแปรเดียวกันกับตัวแปรด้านบน
ในบรรทัดที่สุดท้าย เติม ; ด้านหลังเพื่อจบข้อความในตัวแปร
คัดลอกโค้ดที่ใช้ในการทดลองได้ที่ลิ้ง https://goo.gl/uMza01 จากนั้นแก้ไขส่วน WIFI_STA_NAME และ WIFI_STA_PASS ให้ถูกต้อง แล้วอัพโหลดโค้ดลงบอร์ด NodeMCU-32S ได้เลย
ผลที่ได้คือ ESP32 สามารถดึงข้อมูลผ่าน https มาได้ดังรูป
โค้ดที่ใช้ในการทดลองในครั้งนี้ มีดังนี้
จะเห็นได้ว่าโค้ดส่วนใหญ่จะเหมือนเดิม มีเพียงบรรทัดที่ 7 ถึง 27 ที่มีการสร้างตัวแปร ca มาเพื่อเก็บค่าของ CA และในบรรทัดที่ 58 ได้มีการเพิ่มพารามิเตอร์ ca ในฟังก์ชั่นย่อย .begin() นอกจากนี้ลิ้งในบรรทัดที่ 53 เปลี่ยนไปใช้ https:// แทน
ในบทนี้จะเป็นเรื่องของการใช้งาน HTTP เพื่อดึงข้อมูลและสื่อสารกับเซิร์ฟเวอร์โดยใช้ API เบื้องต้น โดยจะแบ่งใช้งานเป็น HTTP และ HTTPS การใช้งาน HTTPS จะต้องหาค่า CA มาใส่ในโค้ดเพื่อให้สามารถดึงข้อมูลมาได้ ทั้งนี้การรับ-ส่งข้อมูลผ่านโปรโตคอล HTTP จะต้องส่งข้อมูลไปให้เซิร์ฟเวอร์ก่อน การส่งข้อมูลไปให้เซิร์ฟเวอร์จะแบ่งเป็นคำสั่งร้องขอได้ 2 แบบที่นิยมใช้งานกัน คือ GET และ POST มีข้อแตกต่างกันที่แบบ GET จะข้อมูลที่ส่งไปให้เซิร์ฟเวอร์ผ่านลิ้ง แต่แบบ POST จะแฝงไปกับส่วนหัวตอนร้องขอข้อมูล ซึ่งผู้ใช้ไม่สามารถส่งข้อมูลไปได้ด้วยตนเอง และเซิร์ฟเวอร์มีการตอบกลับผลการร้องขอด้วยรหัสสถานะภาพ โดยรหัสเป็น 200 จะหมายถึงร้องขอสำเร็จ การใช้บริการเซิร์ฟเวอร์แต่ละที่จะมีการกำหนดรูปแบบการร้องขอที่แตกต่างกัน ดังนั้นจึงต้องศึกษารูปแบบของการส่งข้อมูลผ่าน HTTP โดยใช้เอกสารของผู้ให้บริการเซิร์ฟเวอร์เป็นหลัก