นี่คือแอปพลิเคชันสาธิตและตัวอย่างที่ออกแบบมาให้เป็นระบบแชทบนเว็บที่มีผู้ใช้หลายคนอย่างง่าย
มีการแชทกลุ่มแบบถาวร การแชทส่วนตัวระหว่างผู้ใช้กับผู้ใช้ รายชื่อผู้ใช้ การตรวจจับการไม่ได้ใช้งาน (อยู่ห่างจากแป้นพิมพ์) และคุณสมบัติอื่น ๆ อีกมากมาย
สร้างขึ้นจากเทคโนโลยี Azure หลายอย่าง รวมถึง: Web PubSub, Static Web Apps และ Table Storage
?? บันทึก. สิ่งนี้สร้างขึ้นเป็นโปรเจ็กต์ส่วนตัว สร้างขึ้นเพื่อช่วยในการเรียนรู้ควบคู่ไปกับการสร้างสิ่งที่น่าสนใจ รหัสนี้มาพร้อมกับคำเตือนทั้งหมดที่คุณอาจคาดหวังจากโครงการดังกล่าว
เป้าหมาย:
กรณีการใช้งานและคุณสมบัติที่สำคัญ:
นี่คือส่วนหน้าของเว็บหลักที่ผู้ใช้ปลายทางใช้ผ่านเบราว์เซอร์
พบแหล่งที่มาของสิ่งนี้ใน ไคลเอนต์/ และประกอบด้วยแอปพลิเคชัน ES6 JS ล้วนแบบสแตนด์อโลนแบบคงที่ ไม่จำเป็นต้องรวมกลุ่มหรือ Node.js เขียนโดยใช้ Vue.js เป็นเฟรมเวิร์กสนับสนุน และใช้ Bulma เป็นเฟรมเวิร์ก CSS
หมายเหตุบางประการ:
client/js/app.js
แสดงวิธีสร้างแอป Vue.js ด้วยคอมโพเนนต์ลูกโดยใช้วิธีนี้ ตรรกะไคลเอนต์ส่วนใหญ่อยู่ที่นี่client/js/components/chat.js
เป็นส่วนประกอบ Vue.js ที่ใช้ในการโฮสต์แต่ละแท็บแชทในแอปพลิเคชัน.auth/
พิเศษที่จัดทำโดย Static Web Apps ใช้เพื่อลงชื่อเข้าใช้ผู้ใช้และดึงรายละเอียดผู้ใช้ เช่น userIdนี่คือแบ็กเอนด์ที่จัดการเหตุการณ์ websocket เข้าและออกจาก Azure Web PubSub และจัดเตรียม REST API สำหรับการดำเนินการบางอย่าง
แหล่งที่มาของสิ่งนี้พบได้ใน api/ และประกอบด้วยแอปฟังก์ชัน Azure ของ Node.js เชื่อมต่อกับ Azure Table Storage เพื่อคงการแชทเป็นกลุ่มและข้อมูลผู้ใช้ (Table Storage ถูกเลือกเนื่องจากง่ายและราคาถูก) สิ่งนี้ไม่ได้โฮสต์ในแอปฟังก์ชัน Azure แบบสแตนด์อโลน แต่ปรับใช้ใน Static Web App แทนซึ่งเป็นส่วนหนึ่งของการสนับสนุน API แบบไร้เซิร์ฟเวอร์
มีฟังก์ชัน HTTP สี่ฟังก์ชันที่ทำงานจากเส้นทาง /api/
เริ่มต้น
eventHandler
- ตัวรับ Webhook สำหรับเหตุการณ์ "อัปสตรีม" ที่ส่งจากบริการ Azure Web PubSub ประกอบด้วยตรรกะแอปพลิเคชันส่วนใหญ่ ลูกค้าไม่ได้เรียกโดยตรง มีเพียง Azure WebPub Sub เท่านั้นgetToken
- ไคลเอ็นต์เรียกเพื่อรับโทเค็นการเข้าถึงและ URL เพื่อเชื่อมต่อผ่าน WebSockets ไปยังบริการ Azure Web PubSub จะต้องเรียกด้วย userId ในการสืบค้น URL เช่น GET /api/getToken?userId={user}
getUsers
- ส่งคืนรายชื่อผู้ใช้ที่ลงชื่อเข้าใช้ โปรดทราบว่าเส้นทางสำหรับฟังก์ชันนี้คือ /api/users
getChats
- ส่งคืนรายการแชทกลุ่มที่ใช้งานอยู่ โปรดทราบว่าเส้นทางสำหรับฟังก์ชันนี้คือ /api/chats
สถานะได้รับการจัดการด้วย state.js
ซึ่งเป็นโมดูล ES6 ที่ส่งออกฟังก์ชันที่รองรับ CRUD สถานะสำหรับผู้ใช้และการแชท โมดูลนี้ดำเนินการโต้ตอบทั้งหมดกับ Azure Tables และมีอินเทอร์เฟซที่ค่อนข้างโปร่งใส ดังนั้นจึงสามารถเปลี่ยนแบ็กเอนด์พื้นที่เก็บข้อมูลอื่นได้
มีการรับส่งข้อความสองทางระหว่างไคลเอนต์และเซิร์ฟเวอร์ผ่าน Azure Web PubSub และตัวจัดการเหตุการณ์
มีการใช้โปรโตคอลย่อย json.webpubsub.azure.v1 แทนที่จะเป็น WebSockets พื้นฐาน ซึ่งมีคุณสมบัติหลายประการ: คุณสามารถเพิ่มผู้ใช้ในกลุ่มได้ ไคลเอนต์สามารถส่งเหตุการณ์ที่กำหนดเอง (โดยใช้ type: event
) และยังส่งข้อความโดยตรงไปยังไคลเอนต์อื่น ๆ โดยไม่ต้องผ่านเซิร์ฟเวอร์ (ใช้ type: sendToGroup
)
หมายเหตุ:
กิจกรรมและการแชทจะถูกส่งโดยใช้โปรโตคอลย่อย json.webpubsub.azure.v1
ข้อความแชทที่ส่งจากไคลเอนต์ใช้ sendToGroup
และเพย์โหลด JSON แบบกำหนดเองพร้อม message
สามฟิลด์ fromUserId
& fromUserName
ข้อความเหล่านี้จะถูกส่งต่อไคลเอนต์ไปยังไคลเอนต์โดย Azure Web PubSub เซิร์ฟเวอร์จะไม่ได้รับการแจ้งเตือน:
{
type : 's endToGroup ',
group : < chatId > ,
dataType : 'j son ',
data : {
message : < message text > ,
fromUserId : < userId > ,
fromUserName : < userName > ,
},
}
กิจกรรมที่กำหนดไว้สำหรับเซิร์ฟเวอร์แบ็กเอนด์จะถูกส่งเป็นข้อความ WebSocket จากไคลเอนต์ผ่านโปรโตคอลย่อยเดียวกันกับประเภท event
และประเภทย่อยเฉพาะแอปพลิเคชัน เช่น
{
type : 'e vent ',
event : 'j oinChat ',
dataType : 't ext ',
data : < chatId > ,
}
ประเภทของเหตุการณ์คือ:
ฟังก์ชัน eventHandler
ของ API แบ็กเอนด์มีเคสสำหรับเหตุการณ์ผู้ใช้แต่ละเหตุการณ์ พร้อมด้วยตัวจัดการสำหรับเหตุการณ์ระบบการเชื่อมต่อและการตัดการเชื่อมต่อ
ข้อความที่ส่งจากเซิร์ฟเวอร์จะมีเพย์โหลดเฉพาะของแอป Chatr แบบกำหนดเองดังต่อไปนี้:
{
chatEvent : < eventType > ,
data : < JSON object type dependant >
}
โดยที่ eventType
เป็นหนึ่งใน:
รหัสไคลเอนต์ใน client/js/app.js
จัดการข้อความเหล่านี้ตามที่ลูกค้าได้รับและตอบสนองตามนั้น
แผนของโปรเจ็กต์นี้คือการใช้ Azure Web PubSub และ Azure Static Web Apps และโฮสต์ส่วนประกอบฝั่งเซิร์ฟเวอร์เป็นชุดของฟังก์ชันไร้เซิร์ฟเวอร์ในการรองรับ Static Web Apps API (ซึ่งจริงๆ แล้วคือ ฟังก์ชัน Azure ภายใต้ประทุน) เลือก Azure Static Web Apps เนื่องจากมีการสนับสนุนที่ยอดเยี่ยมสำหรับการลงชื่อเข้าใช้และรับรองความถูกต้องของผู้ใช้โดยไม่ต้องใช้รหัสและไม่ต้องกำหนดค่า ซึ่งฉันต้องการใช้ประโยชน์
ความคิดเห็นบางส่วนเกี่ยวกับแนวทางนี้:
webPubSubConnection
สำหรับการส่งข้อความกลับไปยัง Web PubSub คุณสามารถใช้ SDK เซิร์ฟเวอร์ภายในโค้ดฟังก์ชันได้ แทนที่จะใช้การเชื่อมโยงเอาต์พุต webPubSub
สถานะใน Azure Tables ประกอบด้วยสองตาราง (คอลเลกชัน) ที่มีชื่อ chats
และ users
เนื่องจากแต่ละแชทมีอ็อบเจ็กต์ที่ซ้อนกันอยู่ภายในช่องสมาชิก แต่ละแชทจึงถูกจัดเก็บเป็นสตริง JSON ในช่องที่เรียกว่า data
PartitionKey ไม่ได้ใช้และฮาร์ดโค้ดเป็นสตริง "chatr" RowKey และฟิลด์ id ภายในออบเจ็กต์ข้อมูลเหมือนกัน
ตัวอย่างของเอนทิตีข้อมูลการสนทนา
{
"id" : " eab4b030-1a3d-499a-bd89-191578395910 " ,
"name" : " This is a group chat " ,
"members" : {
"0987654321" : {
"userId" : " 0987654321 " ,
"userName" : " Another Guy "
},
"1234567890" : {
"userId" : " 1234567890 " ,
"userName" : " Ben "
}
},
"owner" : " 1234567890 "
}
ผู้ใช้จะถูกจัดเก็บเป็นเอนทิตีพร้อมกับฟิลด์ (คอลัมน์) ที่อธิบายไว้ด้านล่าง เนื่องจากไม่มีฟิลด์ที่ซ้อนกัน จึงไม่จำเป็นต้องเข้ารหัสเป็นสตริง JSON อีกครั้งที่ PartitionKey ไม่ได้ถูกใช้และฮาร์ดโค้ดเป็นสตริง "chatr"
userId
ที่ส่งคืนจากจุดสิ้นสุดการตรวจสอบสิทธิ์ Web Apps แบบคงที่twitter
, aad
หรือ github
ดูที่ เมคไฟล์
$ make
help This help message
lint ? Lint & format, will not fix but sets exit code on error
lint-fix Lint & format, will try to fix errors and modify code
run ? Run server locally using Static Web Apps CLI
clean ? Clean up project
deploy Deploy everything to Azure using Bicep
tunnel ? Start loophole tunnel to expose localhost
การปรับใช้มีความซับซ้อนเล็กน้อยเนื่องจากจำนวนส่วนประกอบและการกำหนดค่าระหว่างส่วนประกอบเหล่านั้น deploy
เป้าหมาย makefile ควรปรับใช้ทุกอย่างให้คุณในขั้นตอนเดียวโดยใช้เทมเพลต Bicep ที่พบในโฟลเดอร์ ปรับใช้ /
ดู readme ในโฟลเดอร์ปรับใช้สำหรับรายละเอียดและคำแนะนำ
สิ่งนี้เป็นไปได้แต่ต้องใช้ความพยายามเพียงเล็กน้อย เนื่องจากบริการ Azure Web PubSub จำเป็นต้องสามารถเรียกตำแหน่งข้อมูล HTTP บนเครื่องระบุตำแหน่งของคุณได้ ดังนั้นจึงมีการใช้ทันเนล
เมื่อทำงานภายในเครื่อง จะใช้ Static Web Apps CLI และทำให้มีจุดสิ้นสุดการตรวจสอบสิทธิ์ผู้ใช้ปลอมสำหรับเรา
สรุปขั้นตอนคือ:
api/local.settings.sample.json
ไปยัง api/local.settings.json
และแก้ไขค่าการตั้งค่าที่จำเป็นloophole http 7071 --hostname chatr
https://{{hostname-of-tunnel-service}}/api/eventHandler
make run
http://localhost:4280/index.html