ตอนนี้ คุณมีรายการเกมในตารางของคุณแล้ว ก็สามารถเรียนรู้วิธีการจำลองผู้ใช้ที่กำลังเคลื่อนไหวในเกมที่ดำเนินการอยู่ได้
วิธีจัดการการดำเนินการนี้มีอยู่สองวิธี ในวิธีแรก คุณจะดึงข้อมูลรายการโดยใช้ GetItem API จากนั้น คุณจะอัปเดตรายการเกมในแอปพลิเคชันของคุณตามการเคลื่อนไหวของผู้เล่น สุดท้าย คุณจะแทนที่รายการที่อยู่ใน DynamoDB โดยใช้ PutItem API แม้ว่าตัวเลือกนี้จะใช้งานได้ แต่ก็ต้องส่งคำขอหลายรายการไปยังตาราง DynamoDB ของคุณและเสี่ยงต่อการเขียนทับการเปลี่ยแปลงที่เกิดขึ้นระหว่างการดึงข้อมูลและการเขียนรายการเกมใหม่
วิธีที่สองในการจัดการการดำเนินการนี้คือการเรียกใช้ UpdateItem API ใน DynamoDB เมื่อใช้ UpdateItem API คุณจะอัปเดตรายการ DynamoDB ด้วยคำขอเดียวได้ คุณระบุรายการที่คุณต้องการเปลี่ยนแปลง แอตทริบิวต์ที่จะเปลี่ยนแปลง และเงื่อนไขที่ต้องการยืนยันกับรายการ เราขอแนะนำให้ใช้วิธีนี้ในการเปลี่ยนแปลงรายการ เนื่องจากไม่จำเป็นต้องเรียกใช้ฐานข้อมูลหลายครั้ง
ในไดเรกทอรี scripts/ จะมีไฟล์ที่ชื่อว่า performMove.js ซึ่งมีเนื้อหาต่อไปนี้:
const AWS = require('aws-sdk')
const documentClient = new AWS.DynamoDB.DocumentClient()
const performMove = async ({ gameId, user, changedHeap, changedHeapValue }) => {
if (changedHeapValue < 0 ) {
throw new Error('Cannot set heap value below 0')
}
const params = {
TableName: 'turn-based-game',
Key: {
gameId: gameId
},
UpdateExpression: `SET lastMoveBy = :user, ${changedHeap} = :changedHeapValue`,
ConditionExpression: `(user1 = :user OR user2 = :user) AND lastMoveBy <> :user AND ${changedHeap} > :changedHeapValue`,
ExpressionAttributeValues: {
':user': user,
':changedHeapValue': changedHeapValue,
},
ReturnValues: 'ALL_NEW'
}
try {
const resp = await documentClient.update(params).promise()
console.log('Updated game: ', resp.Attributes)
} catch (error) {
console.log('Error updating item: ', error.message)
}
}
performMove({ gameId: '5b5ee7d8', user: 'theseconduser', changedHeap: 'heap1', changedHeapValue: 3 })
สคริปต์นี้ซับซ้อนเล็กน้อย ดังนั้น เราจะอธิบายทีละขั้นตอน
เหมือนกับสคริปต์ก่อนหน้านี้ คือคุณนำเข้า AWS SDK และสร้างอินสแตนซ์ DynamoDB Document Client
จากนั้น คุณกำหนดวิธีการที่เรียกว่า performMove วิธีนี้จะคล้ายกับวิธีการภายในที่ใช้ในแอปพลิเคชันของคุณ เมื่อผู้ใช้ร้องขอการเคลื่อนไหว สคริปต์จะรวบรวมพารามิเตอร์สำหรับการเรียกใช้ UpdateItem API อันดับแรก จะเปลี่ยนสองแอตทริบิวต์ของเกมคือ ผู้ใช้ล่าสุดที่เคลื่อนไหวและจำนวนขององค์ประกอบในฮีปที่เปลี่ยนแปลง
จากนั้น พารามิเตอร์ UpdateItem API จะยืนยันเกี่ยวกับสถานะปัจจุบันของเกม ConditionExpression จะได้รับการประเมินก่อนที่จะอัปเดตรายการเพื่อยืนยันว่ารายการมีสถานะตามที่คุณต้องการ คุณกำลังยืนยันสามรายการต่อไปนี้ในการแสดงเงื่อนไขของคุณ:
- ผู้ใช้ที่ร้องขอการเคลื่อนไหวคือหนึ่งในผู้ใช้สองรายในเกม
- รอบปัจจุบันเป็นของผู้ใช้ที่ร้องขอการเคลื่อนไหว
- ฮีปที่กำลังเปลี่ยนแปลงมีค่าปัจจุบันสูงกว่าค่าที่จะเปลี่ยน
สุดท้าย พารามิเตอร์ระบุ ReturnValue ของ ALL_NEW ซึ่งหมายความว่า DynamoDB ส่งกลับรายการทั้งหมดหลังจากอัปเดตค่าแล้ว เมื่อคุณมาถึงขั้นตอนนี้ แอปพลิเคชันของคุณจะประเมินเกมได้เพื่อดูว่ามีผู้ชนะหรือไม่
ทางด้านล่างของไฟล์จะมีตัวอย่างการเรียกใช้วิธีนี้ในแอปพลิเคชันของคุณ คุณปฏิบัติการสคริปต์ได้ด้วยคำสั่งต่อไปนี้:
คุณควรจะเห็นผลลัพธ์ต่อไปนี้ในเทอร์มินัลของคุณ:
Updated game: { heap2: 4,
heap1: 3,
heap3: 5,
gameId: '5b5ee7d8',
user2: 'theseconduser',
user1: 'myfirstuser',
lastMoveBy: 'theseconduser' }
คุณจะเห็นว่าการเขียนสำเร็จแล้วและเกมได้รับการอัปเดตแล้ว
ลองเรียกใช้สคริปต์อีกครั้งในเทอร์มินัลของคุณ คุณจะเห็นผลลัพธ์ต่อไปนี้:
คำขอแบบมีเงื่อนไขของคุณล้มเหลวในครั้งนี้ ผู้ใช้ที่ร้องขอ – theseconduser – คือผู้ใช้ที่มีการเคลื่อนไหวล่าสุด นอกจากนี้ ฮีปที่เปลี่ยนแปลง – heap1 – มีค่า 3 อยู่แล้ว แสดงว่าผู้ใช้ไม่ได้เปลี่ยนแปลงอะไร ดังนั้น คำขอจึงถูกปฏิเสธ