ยูทิลิตี้ที่หลากหลายสำหรับโมดูลอื่นๆ รวม LambdaReflection
ซึ่งอนุญาตให้ตั้งค่าและรับค่าฟิลด์ของอินสแตนซ์หรือตัวสร้างการเข้าถึงผ่านอินเทอร์เฟซการทำงานที่สร้างโดย LambdaMetafactory
ไลบรารีการทำให้เป็นอนุกรมเชิงนามธรรมที่รองรับการใช้งานบัฟเฟอร์ใดๆ โดยอัตโนมัติ (de-) ทำให้คลาสเป็นอนุกรมที่ทำเครื่องหมายด้วย @AutoSerializable
ซึ่งประกอบด้วยฟิลด์ประเภทเริ่มต้น การใช้งาน Proto4jSerializable
หรือสมาชิก @AutoSerializable
อื่น ๆ
รองรับการสืบทอดด้วย: คลาสที่ทำให้เป็นอนุกรมสามารถขยาย @AutoSerializable
อื่น ๆ ได้ ซึ่งในกรณีนี้ฟิลด์พาเรนต์ทั้งหมดจะกลายเป็นอนุกรมแบบทรานซิชันด้วย
ฟิลด์ที่ควรละเว้นในระหว่างการทำให้เป็นอนุกรมควรมีคำอธิบายประกอบด้วย @Transient
ไลบรารีเครือข่ายพร้อมการใช้งานตาม UDP แบบกำหนดเองพร้อมความน่าเชื่อถือที่กำหนดค่าได้
Proto4jServer
และ Proto4jClient
ช่วยให้คุณสามารถถ่ายโอนข้อมูลโดยใช้ดาตาแกรมระหว่างซ็อกเก็ต
ตามค่าเริ่มต้น ข้อมูลที่ส่งใดๆ จะได้รับการจัดลำดับ เชื่อถือได้ และได้รับอนุญาตให้แบ่งออกเป็นแพ็กเก็ต UDP หลายชุด และรวมกลับมาที่ฝั่งผู้รับ และรับประกันว่าจะมีการส่ง
แพ็กเก็ต UDP ทั้งหมดที่ถูกส่งมีโครงสร้างต่อไปนี้:
คุณสามารถเลือกวิธีการส่งข้อมูลได้ สามารถกำหนดค่าได้โดยการระบุแฟล็กสำหรับวิธีการส่ง ทั้งหมดอยู่ใน Proto4jPacket
Flag
.
มีธงต่อไปนี้:
ชื่อ | ค่า | ความหมาย |
---|---|---|
CONFIRMATION | 0x01 | ทำเครื่องหมายว่าแพ็กเก็ตนี้เป็นตัวบ่งชี้ว่าได้รับแพ็กเก็ตอื่นสำเร็จแล้ว จำเป็นสำหรับความน่าเชื่อถือในการส่งผ่าน โดยทั่วไปสำหรับการใช้งานภายในเท่านั้น |
PARTIAL | 0x02 | ทำเครื่องหมายว่าแพ็กเก็ต UDP ที่แน่นอนนี้เป็นส่วนหนึ่งของแพ็กเก็ตที่ใหญ่กว่า เมื่อใช้ร่วมกับแฟล็ก CONFIRMATION ร่วมกัน แสดงว่าแพ็กเก็ตขนาดใหญ่บางส่วนถูกส่งไปแล้ว |
UNORDERED | 0x04 | ทำเครื่องหมายว่าแพ็กเก็ตนี้สามารถจัดการไม่เป็นระเบียบได้ |
UNSIGNED_BODY | 0x08 | ตามค่าเริ่มต้น แพ็กเก็ตที่ส่งทั้งหมดจะถูกเซ็นชื่อโดยใช้ CRC32 แต่สำหรับแพ็กเก็ตที่มีแฟล็กที่ระบุเฉพาะส่วนหัวของแพ็กเก็ตเท่านั้นที่จะถูกเซ็นชื่อ ซึ่งหมายความว่าแพ็กเก็ตอาจมีไบต์ที่ไม่ถูกต้อง (แม้ว่าจะยังไม่รับประกันว่าข้อมูลจะสูญหายก็ตาม) |
UNRELIABLE | 0x10 | ทำเครื่องหมายแพ็กเก็ตนี้ว่าไม่ต้องการการยืนยัน ในกรณีที่ผู้รับไม่ได้รับแพ็กเก็ตนี้ ผู้ส่งจะไม่ทำอะไรกับมัน |
INDIVISIBLE | 0x20 | แพ็กเก็ต UDP มีความยาวจำกัด ดังนั้น Proto4J จึงแบ่งข้อมูลขนาดใหญ่ออกเป็นแพ็กเก็ตขนาดเล็กหลายแพ็กเก็ต แฟล็กนี้บ่งชี้ว่าในกรณีที่แพ็กเก็ตเกินขีดจำกัดขนาดของแพ็กเก็ตเดียว ข้อยกเว้นจะถูกส่งออกไปแทนการแยก |
ไม่รองรับการจับมือหรือการกระตุกในระดับนี้ แต่คุณสามารถตั้งค่าตัวจัดการแพ็กเก็ตของคุณเองได้โดยใช้วิธี Proto4jSocket
.setInitialPacketHandler(BiConsumer<C, Proto4jPacket>)
แพ็กเก็ตที่มาถึงจุดนี้จะไม่ถูกทำเครื่องหมายด้วยแฟล็ก CONFIRMATION
หรือ PARTIAL
ดังนั้นอินสแตนซ์ Proto4jPacket
ทั้งหมดที่จัดการที่นั่นจึงมีข้อมูลที่แน่นอนที่ส่งโดยผู้ส่ง (ขึ้นอยู่กับแฟล็ก UNSIGNED_BODY
)
นอกจากนี้ เมื่อคุณเริ่มซ็อกเก็ต CompletionStage<Void>
จะถูกส่งกลับซึ่งอาจช่วยคุณในการเริ่มต้นตรรกะของการสื่อสารระหว่างซ็อกเก็ต
เมื่อคุณกำลังจะสร้างอินสแตนซ์ของซ็อกเก็ตใด ๆ ใน Proto4J คุณจะต้องส่งจำนวนเธรดของผู้ปฏิบัติงานและตัวจัดการไปยังตัวสร้างซ็อกเก็ต
ผู้ปฏิบัติงาน ใช้สำหรับการอ่านข้อมูลจากซ็อกเก็ตเท่านั้น
ตัวจัดการ ใช้สำหรับการจัดการตรรกะเมื่อมีแพ็กเก็ตใหม่ปรากฏขึ้น
นี่คืออินเทอร์เฟซระดับที่สูงกว่าระดับก่อนหน้า หากต้องการเริ่มทำงาน ให้ดูที่ Proto4jHighServer
และ Proto4jHighClient
หรือการใช้งานพื้นฐาน: BaseProto4jHighServer
และ BaseProto4jHighClient
เมื่อไคลเอนต์โต้ตอบกับเซิร์ฟเวอร์ในตอนแรกจะเริ่ม การจับมือกัน หลังจากเสร็จสิ้นเซิร์ฟเวอร์และไคลเอนต์จะ ping ซึ่งกันและกันเพื่อให้แน่ใจว่าการเชื่อมต่อจะไม่ขาดหาย
ตรงกันข้ามกับ Low Level คุณสามารถส่งแพ็กเก็ตระดับสูงผ่านเครือข่ายได้ ไม่เพียงแต่โดยการจัดการไบต์ดิบเท่านั้น แต่ยังใช้เอนทิตีที่ซับซ้อนอีกด้วย โดยสร้างคลาสของคุณเองที่ขยาย EnumeratedProto4jPacket
หรือ CallbackProto4jPacket
สิ่งที่คุณต้องทำเพื่อให้มันใช้งานได้คือใช้วิธี write(Buffer)
และ read(Buffer)
และลงทะเบียนแพ็กเก็ตของคุณใน PacketManager
ทั้งสองด้าน
นอกจากนี้ยังมีคลาส PacketHandler
ทางเลือกซึ่งทำงานกับแพ็กเก็ตเหล่านั้นแทน Proto4jPacket
s
เป็นสถานการณ์ทั่วไปที่ต้องรอให้แพ็กเก็ตบางตัวตอบสนองต่อแพ็กเก็ตที่ส่งไป ฟังก์ชันเหล่านี้ได้รับการใช้งานแล้วในระดับนี้ คุณสามารถระบุเวลารอสูงสุดและจัดการการตอบกลับได้ตามที่คุณต้องการ ซึ่งสามารถทำได้โดยการส่งแพ็กเก็ตเริ่มต้นโดยใช้ HighChannel
วิธีการ sendWithCallback(CallbackProto4jPacket)
ต่อไปนี้เป็นรายการคุณสมบัติของระบบที่สามารถใช้เพื่อส่งผลต่อวิธีการทำงานของโมดูลภายใน ค่าเวลาทั้งหมดระบุเป็นมิลลิวินาที
ชื่อ | ค่าเริ่มต้น | คำอธิบาย |
---|---|---|
proto4j.maxDatagramSize | 508 | ขนาดเดตาแกรมสูงสุดที่อนุญาต โปรดทราบว่าระบบจะนับขนาดแพ็กเก็ต UDP ทั้งหมด |
proto4j.maxSequenceNumber | 2_000_000_000 | หมายเลขลำดับสูงสุดของแพ็กเก็ต เมื่อตัวนับภายในถึงค่านี้ ตัวนับจะรีเซ็ตเป็นศูนย์ |
proto4j.reliabilityThreshold | 20 | ความล่าช้าของแพ็กเก็ตที่ไม่ได้รับการยืนยัน (และไม่ได้ทำเครื่องหมายด้วยธง UNRELIABLE ) |
proto4j.callbacksRegistryDelay | 100 | อัตราที่การตรวจสอบรีจิสทรีของการโทรกลับดึงข้อมูลการโทรกลับที่หมดเวลา |
proto4j.callbacksInitialDelay | 500 | เป็นเวลาเริ่มต้นที่ใช้เมื่อใดก็ตามที่มีการส่งแพ็กเก็ตและรอเมื่อใดก็ตามที่ไม่ได้ระบุเวลาที่รอไว้อย่างชัดเจน |
proto4j.highTimeout | 10_000 | หากเซิร์ฟเวอร์ไม่ได้รับแพ็กเก็ตใด ๆ จากไคลเอนต์เป็นเวลานานเซิร์ฟเวอร์จะตัดการเชื่อมต่ออันหลัง |
proto4j.highPingDelay | 1_000 | หากเซิร์ฟเวอร์ระบุว่าไม่มีการรับหรือส่งไปยังไคลเอนต์เป็นเวลานานขนาดนั้น เซิร์ฟเวอร์จะส่งการตอบกลับไปยังเซิร์ฟเวอร์หลังและรอแพ็กเก็ต Ping |
นี่คือ API ระดับที่สูงกว่า ระดับหนึ่งระดับสูง แทนที่จะใช้แพ็กเก็ตและการจัดการด้วยตนเอง คุณทำงานผ่านบริการ
หากต้องการเริ่มทำงานให้ใช้ RpcServer
และ RpcClient
เซิร์ฟเวอร์ในระดับนี้ใช้เพื่อวัตถุประสงค์ในการกำหนดเส้นทางเท่านั้น แต่ไคลเอนต์ทำหน้าที่เป็นทั้งผู้ใช้บริการและผู้นำไปใช้
บริการประกอบด้วยอินเทอร์เฟซและส่วนการใช้งาน ในฐานะผู้ใช้บริการ คุณสามารถรับอินสแตนซ์อินเทอร์เฟซบริการผ่าน RpcClient
.getServiceManager().getService(Class<S>)
วิธีการทั้งหมดจะพร็อกซีกับการใช้งานที่ลงทะเบียนไว้ และจะดำเนินการจากระยะไกล
หากต้องการสร้างบริการของคุณเอง ให้เริ่มต้นด้วยอินเทอร์เฟซและใส่คำอธิบายประกอบด้วย @Proto4jService
อินเทอร์เฟซบริการได้รับอนุญาตให้มีวิธีการเริ่มต้นและแบบคงที่ แต่ประเภทการส่งคืนจะต้องเป็น void
, serializable หรือ CompletionStage
ของประเภทก่อนหน้า นอกจากนี้ อาร์กิวเมนต์ทั้งหมดจะต้องทำให้เป็นอนุกรมได้
ประเภทที่ทำให้เป็นอนุกรมมีดังต่อไปนี้:
String
และ UUID
@AutoSerializable
BufferSerializable
List
Set
และ Map
ของประเภทที่ทำให้ซีเรียลไลซ์ได้ หากควรดำเนินการวิธีการกับการใช้งานบริการที่ลงทะเบียนไว้ทั้งหมด ก็ควรใส่คำอธิบายประกอบด้วย @Broadcast
อย่างไรก็ตาม วิธีการดังกล่าวสามารถส่งคืนได้เฉพาะ void
หรือ CompletionStage<Void>
เท่านั้น
ตามค่าเริ่มต้น เมื่อคุณเรียกใช้เมธอดนั้น มันจะถูกดำเนินการในการใช้งานแบบสุ่ม หากคุณต้องการควบคุมการกระจายการดำเนินการ ให้ทำเครื่องหมายอาร์กิวเมนต์บางส่วนของวิธีการด้วย @Index
: เมื่อใดก็ตามที่วิธีการถูกเรียกใช้ การใช้งานจะถูกเลือกตามรหัสแฮชของอาร์กิวเมนต์ที่ทำเครื่องหมายไว้
เมื่อใดก็ตามที่มีการลงทะเบียนบริการ วิธีการทั้งหมดจะถูกแปลงเป็นตัวระบุจำนวนเต็ม ไม่สามารถมีสองวิธีที่มีตัวระบุเดียวกัน แต่สถานการณ์ดังกล่าวอาจเกิดขึ้นได้ ในการจัดการกับมัน ให้ใส่คำอธิบายประกอบวิธีการด้วย @MethodIdentifier
พร้อมด้วยตัวระบุคงที่ที่ระบุอย่างชัดเจน
เมื่อคุณสร้างอินเทอร์เฟซบริการแล้ว ให้สร้างการใช้งานและลงทะเบียนโดยใช้ RpcClient
.getServiceManager().registerService(Class<S>, I)
สถานการณ์ทั่วไปคือการมีอินเทอร์เฟซบริการบนไคลเอนต์สองชุด แต่มีการใช้งานเพียงชุดเดียวเท่านั้น
นี่คือเลเยอร์ระดับที่สูงกว่า RPC พื้นฐาน
เมื่อสร้างแบ็กเอนด์แบบกระจาย (เช่น ไมโครเซอร์วิส) แนวทางปฏิบัติที่ดีคือการลดจำนวนจุดที่เกิดความล้มเหลว มีเพียงจุดเดียวของความล้มเหลวในรูปแบบที่อธิบายไว้ในส่วนก่อนหน้านี้ซึ่งเป็นอินสแตนซ์เซิร์ฟเวอร์เดียว Conclave คือชุดเซิร์ฟเวอร์ที่ทำงานพร้อมกัน
เซิร์ฟเวอร์ทั้งหมดบน Conclave เชื่อมต่อถึงกัน แต่ไคลเอนต์ทุกตัวเชื่อมต่อกับเซิร์ฟเวอร์เดียวเท่านั้น การสืบค้น RPC มีการกระจายและกำหนดเส้นทางอย่างดีทั่วทั้งเครือข่าย เพื่อให้คุณไม่ต้องกังวลกับเรื่องนี้
หากต้องการเริ่มทำงานกับ Conclave ให้ดูที่ RpcConclaveServer
และ RpcConclaveClient
หากต้องการสร้างอินสแตนซ์ใด ๆ คุณจะต้องผ่าน List<InetSocketAddress>
- รายการจุดปลายทางของเซิร์ฟเวอร์ทั้งหมด
สำหรับโมดูล Transport มีชุดคุณสมบัติระบบที่กำลังค้นหาในโมดูล RPC
ชื่อ | ค่าเริ่มต้น | คำอธิบาย |
---|---|---|
proto4j.conclaveWorkers | 2 | จำนวนเธรดผู้ปฏิบัติงานที่ใช้โดยไคลเอ็นต์ภายในเซิร์ฟเวอร์แต่ละเครื่อง (ซึ่งใช้เพื่อเข้าถึงเซิร์ฟเวอร์อื่น) |
proto4j.conclaveHandlers | 2 | จำนวนเธรดตัวจัดการที่ใช้โดยไคลเอนต์ภายในเซิร์ฟเวอร์แต่ละตัว (ซึ่งถูกใช้เพื่อเข้าถึงเซิร์ฟเวอร์อื่น) |
proto4j.conclaveTimeout | 1_000 | เวลาสูงสุดที่เซิร์ฟเวอร์จะรอจนกว่าการจับมือกับเซิร์ฟเวอร์อื่นจะเสร็จสิ้น มิฉะนั้นจะถือว่าอย่างหลังเป็นการพยายามเชื่อมต่อที่สิ้นสุดเพียงครั้งเดียวซึ่งในกรณีนี้การเชื่อมต่อจะเริ่มต้นใหม่เฉพาะในกรณีที่มีคำขอจากอีกเครื่องหนึ่งเมื่อเริ่มต้นระบบ |