ไคลเอนต์ AC สำหรับระบบส่งข้อความ NATS
ไปที่นี่เพื่อดูเอกสารออนไลน์ และตรวจสอบคำถามที่พบบ่อย
การใช้งาน NATS Client นี้อิงตาม NATS GO Client เป็นอย่างมาก มีการรองรับ Mac OS/X, Linux และ Windows (แม้ว่าเราจะไม่มีเมทริกซ์รองรับแพลตฟอร์มเฉพาะก็ตาม)
มีตัวจัดการแพ็คเกจหลายตัวพร้อมไลบรารีไคลเอนต์ NATS C ใครรู้จักที่ไม่อยู่ในรายการนี้ กรุณาส่ง PR เพื่อเพิ่มเข้าไปด้วย!
ขั้นแรก ดาวน์โหลดซอร์สโค้ด:
git clone [email protected]:nats-io/nats.c.git .
หากต้องการสร้างไลบรารี่ ให้ใช้ CMake โปรดทราบว่าตามค่าเริ่มต้น NATS Streaming API จะถูกสร้างขึ้นและรวมอยู่ในไลบรารี NATS ดูด้านล่างหากคุณไม่ต้องการสร้าง API ที่เกี่ยวข้องกับการสตรีม
ตรวจสอบให้แน่ใจว่าได้เพิ่ม CMake ลงในเส้นทางของคุณแล้ว หากสร้างบน Windows ให้เปิดเชลล์คำสั่งจากเมนูเครื่องมือ Visual Studio และเลือกเชลล์คำสั่งที่เหมาะสม (x64 หรือ x86 สำหรับบิลด์ 64 หรือ 32 บิตตามลำดับ) คุณอาจต้องเรียกใช้สิ่งนี้ด้วยสิทธิ์ของผู้ดูแลระบบ
สร้างไดเร็กทอรี build
(ชื่อใดก็ได้ที่ใช้งานได้) จากแผนผังต้นทางรากและ cd
ลงไป จากนั้นออกคำสั่งนี้เป็นครั้งแรก:
cmake ..
ในบางสถาปัตยกรรม คุณอาจพบข้อผิดพลาดในการคอมไพล์สำหรับ mutex.co
เนื่องจากไม่มีการรองรับคำสั่งแอสเซมเบลอร์ที่เราใช้เพื่อให้ได้ผลลัพธ์เมื่อพยายามรับการล็อค
คุณอาจได้รับข้อผิดพลาดในการสร้างประเภทนี้:
/tmp/cc1Yp7sD.s: Assembler messages:
/tmp/cc1Yp7sD.s:302: Error: selected processor does not support ARM mode `yield'
src/CMakeFiles/nats_static.dir/build.make:542: recipe for target 'src/CMakeFiles/nats_static.dir/unix/mutex.c.o' failed
หากเป็นกรณีนี้ คุณสามารถแก้ไขได้โดยเปิดใช้งานการตั้งค่าสถานะ NATS_BUILD_NO_SPIN
(หรือใช้ -DNATS_NO_SPIN
หากคุณคอมไพล์โดยไม่มี CMake):
cmake .. -DNATS_BUILD_NO_SPIN=ON
หากคุณเคยสร้างไลบรารีมาก่อน คุณอาจต้องทำการ make clean
หรือเพียงแค่ลบและสร้างไดเร็กทอรี build ใหม่ก่อนที่จะดำเนินการคำสั่ง cmake
หากต้องการสร้างบน Windows คุณจะต้องเลือกตัวสร้างบิลด์ ตัวอย่างเช่น หากต้องการเลือก nmake
คุณจะต้องเรียกใช้:
cmake .. -G "NMake Makefiles"
การรัน cmake -h
จะให้รายการตัวเลือกที่เป็นไปได้และชื่อตัวสร้างทั้งหมด
หรือคุณสามารถเรียกใช้เวอร์ชัน GUI ได้ จากเชลล์คำสั่ง build เดียวกันนั้น ให้เริ่ม GUI:
c:program files (x86)CMakebincmake-gui.exe
หากคุณเริ่มต้นด้วยไดเร็กทอรี build ว่าง คุณจะต้องเลือกแหล่งที่มาและไดเร็กทอรี build จากนั้นคลิก Configure
ที่นี่ คุณจะสามารถเลือกชื่อของตัวสร้างบิลด์จากกล่องดรอปดาวน์ได้ เมื่อเสร็จแล้วให้คลิก Generate
จากนั้นคุณสามารถกลับไปที่เชลล์คำสั่งหรือ Visual Studio และสร้างได้
หากต้องการแก้ไขตัวเลือกการสร้างบางส่วน คุณต้องแก้ไขแคชและสร้างใหม่
make edit_cache
โปรดทราบว่าหากคุณสร้างบน Windows และได้เลือก "NMake Makefiles" ให้แทนที่การอ้างอิงต่อไปนี้ทั้งหมดเพื่อ make
ด้วย nmake
การแก้ไขแคชทำให้คุณสามารถเลือกประเภทบิลด์ (Debug, Release ฯลฯ) สถาปัตยกรรม (64 หรือ 32 บิต) และอื่นๆ
เป้าหมายเริ่มต้นจะสร้างทุกอย่าง นั่นคือ ไลบรารี NATS แบบคงที่และแบบแบ่งใช้ รวมถึงตัวอย่างและโปรแกรมทดสอบด้วย แต่ละรายการจะอยู่ในไดเร็กทอรีของตนภายใต้ไดเร็กทอรี build ของคุณ: src
, examples
และ test
make install
จะคัดลอกทั้งไลบรารีแบบสแตติกและไลบรารีที่แชร์ในโฟลเดอร์ install/lib
และส่วนหัวสาธารณะใน install/include
ตามค่าเริ่มต้น ไลบรารีจะถูกสร้างขึ้นด้วยการสนับสนุน TLS คุณสามารถปิดใช้งานสิ่งนี้ได้จาก cmake gui make edit_cache
และเปลี่ยนตัวเลือก NATS_BUILD_WITH_TLS
เป็น OFF
หรือส่งตัวเลือกโดยตรงไปยังคำสั่ง cmake
:
cmake .. -DNATS_BUILD_WITH_TLS=OFF
ตั้งแต่ 2.0.0
เป็นต้นไป เมื่อสร้างด้วยการสนับสนุน TLS/SSL ชื่อโฮสต์ที่คาดหวังของใบรับรองเซิร์ฟเวอร์จะได้รับการตรวจสอบเสมอ หมายความว่าชื่อโฮสต์ที่ระบุใน URL หรือผ่านตัวเลือก natsOptions_SetExpectedHostname()
จะถูกนำมาใช้เพื่อตรวจสอบชื่อโฮสต์ที่มีอยู่ในใบรับรอง ก่อนหน้า 2.0.0
ชื่อโฮสต์จะถูกตรวจสอบ เฉพาะ เมื่อมีการเรียกใช้ตัวเลือก natsOptions_SetExpectedHostname()
แม้ว่าเราจะแนะนำให้ทิ้งลักษณะการทำงานเริ่มต้นใหม่ไว้ แต่คุณสามารถคืนค่าลักษณะการทำงานก่อนหน้านี้ได้โดยการสร้างไลบรารีโดยปิดตัวเลือกนี้:
cmake .. -DNATS_BUILD_TLS_FORCE_HOST_VERIFY=OFF
ไคลเอนต์ NATS C สร้างขึ้นโดยใช้ API จากไลบรารี OpenSSL ตามค่าเริ่มต้น เราใช้ API 3.0+
เนื่องจากไม่รองรับ OpenSSL 1.0.2
อีกต่อไป ตั้งแต่เวอร์ชัน NATS C Client v3.6.0
เป็นต้นไป ตัวแปร CMake NATS_BUILD_TLS_USE_OPENSSL_1_1_API
จะถูกตั้งค่าเป็น ON
ตามค่าเริ่มต้น (หากคุณกำลังตั้งค่าสภาพแวดล้อมใหม่) และจะใช้ OpenSSL API ตั้งแต่ 1.1+
/ API 3.0+
คุณจะยังคงสามารถคอมไพล์ด้วยไลบรารี OpenSSL 1.0.2
ได้โดยตั้งค่าตัวเลือก CMake นี้เป็น OFF
:
cmake .. -DNATS_BUILD_TLS_USE_OPENSSL_1_1_API=OFF
ตัวแปร NATS_BUILD_TLS_USE_OPENSSL_1_1_API
เลิกใช้งานแล้ว ซึ่งหมายความว่าในอนาคตตัวเลือกนี้จะถูกลบออก และจะใช้เฉพาะ OpenSSL 3.0+
API เท่านั้น รหัสในไลบรารีที่ใช้ OpenSSL API รุ่นเก่าจะถูกลบออกด้วย
โปรดทราบว่าตัวแปร NATS_BUILD_WITH_TLS_CLIENT_METHOD
ที่เลิกใช้แล้วใน v2.0.0
ได้ถูกลบออกไปแล้ว
เนื่องจากไคลเอ็นต์ NATS C ลิงก์ไปยังไลบรารี OpenSSL แบบไดนามิก คุณจึงต้องตรวจสอบให้แน่ใจว่าคุณกำลังใช้งานแอปพลิเคชันของคุณกับไลบรารี OpenSSL 1.1+/3.0+
หากคุณต้องการลิงก์ไปยังไลบรารี OpenSSL แบบคงที่ คุณจะต้องลบ CMakeCache.txt
และสร้างใหม่ด้วยตัวเลือกเพิ่มเติม:
rm CMakeCache.txt
cmake .. -DNATS_BUILD_OPENSSL_STATIC_LIBS=ON
จากนั้นโทร make
(หรือเทียบเท่าขึ้นอยู่กับแพลตฟอร์มของคุณ) และควรตรวจสอบให้แน่ใจว่าไลบรารี (และตัวอย่างและ/หรือชุดทดสอบที่ปฏิบัติการได้) เชื่อมโยงกับไลบรารี OpenSSL หาก CMake พบ
เมื่อสร้างไลบรารีด้วยการรองรับการสตรีม ไลบรารี NATS จะใช้ไลบรารี libprotobuf-c เมื่อ cmake ทำงานเป็นครั้งแรก (หรือหลังจากลบ CMakeCache.txt
และเรียก cmake ..
อีกครั้ง) มันกำลังมองหาไลบรารี libprotobuf-c หากไม่พบ ข้อความจะถูกพิมพ์ และกระบวนการสร้างล้มเหลว CMake ค้นหาไลบรารีในไดเร็กทอรีที่มักจะพบไลบรารี อย่างไรก็ตาม หากคุณต้องการระบุไดเร็กทอรีเฉพาะที่เป็นตำแหน่งของไลบรารี คุณต้องดำเนินการดังนี้:
cmake .. -DNATS_PROTOBUF_DIR=
ไลบรารีแบบคงที่จะถูกใช้เป็นค่าเริ่มต้น หากคุณต้องการเปลี่ยนแปลง หรือหากไลบรารีไม่มีชื่อที่ต้องการ คุณต้องดำเนินการดังนี้:
# Use the library named mylibproto.so located at /my/location
cmake .. -DNATS_PROTOBUF_LIBRARY=/my/location/mylibproto.so
ทั้งสองสามารถรวมกันได้หากส่วนหัวรวมอยู่ในไดเร็กทอรีอื่น
# Use the library named mylibproto.so located at /my/location and the directory protobuf-c/ containing protobuf-c.h located at /my/other/location
cmake .. -DNATS_PROTOBUF_LIBRARY=/my/location/mylibproto.so -DNATS_PROTOBUF_DIR=/my/other/location
หากคุณไม่ต้องการสร้าง NATS Streaming API เพื่อรวมไว้ในไลบรารี NATS:
cmake .. -DNATS_BUILD_STREAMING=OFF
เมื่อใช้คุณสมบัติความปลอดภัย NATS 2.0 ใหม่ ไลบรารีจำเป็นต้องลงนาม "nonce" บางส่วนที่เซิร์ฟเวอร์ส่งมาระหว่างการเชื่อมต่อหรือเชื่อมต่อใหม่ เราใช้ลายเซ็นคีย์สาธารณะ Ed25519 ไลบรารีมาพร้อมกับโค้ดบางส่วนสำหรับดำเนินการลายเซ็น ในกรณีส่วนใหญ่ ก็ไม่เป็นไร แต่หากประสิทธิภาพเป็นปัญหา (โดยเฉพาะอย่างยิ่งหากคุณวางแผนที่จะใช้ฟังก์ชัน natsConnection_Sign()
บ่อยครั้ง คุณจะมีตัวเลือกในการสร้างด้วยไลบรารี Libsodium
ทำตามคำแนะนำเกี่ยวกับวิธีการติดตั้งไลบรารี libsodium ที่นี่
บน macOS คุณสามารถใช้ brew
:
brew install libsodium
บน Linux คุณสามารถใช้ apt-get
apt-get install libsodium-dev
เมื่อติดตั้งแล้ว คุณสามารถสร้างไคลเอนต์ NATS C ขึ้นมาใหม่ได้โดยเปิดใช้งานไลบรารี libsodium ก่อน:
cmake .. -DNATS_BUILD_USE_SODIUM=ON
หากคุณมีไลบรารี libsodium ติดตั้งอยู่ในตำแหน่งที่ไม่ได้มาตรฐานซึ่ง CMake ไม่พบ คุณสามารถระบุตำแหน่งของไดเร็กทอรีนี้ได้:
cmake .. -DNATS_BUILD_USE_SODIUM=ON -DNATS_SODIUM_DIR=/my/path/to/libsodium
บนแพลตฟอร์มที่มี valgrind
คุณสามารถรันการทดสอบด้วยการตรวจสอบหน่วยความจำ นี่คือตัวอย่าง:
make test ARGS="-T memcheck"
หรือคุณสามารถเรียกใช้โปรแกรม ctest
ได้โดยตรง:
ctest -T memcheck -V -I 1,4
คำสั่งดังกล่าวจะรันการทดสอบด้วย valgrind
( -T memcheck
) โดยมีเอาต์พุต verbose ( -V
) และรันการทดสอบตั้งแต่ 1 ถึง 4 ( -I 1,4
)
หากคุณเพิ่มการทดสอบลงใน test/test.c
คุณจะต้องเพิ่มลงในไฟล์ list_test.txt
แต่ละรายการมีเพียงชื่อการทดสอบ ฟังก์ชันจะต้องตั้งชื่อให้เหมือนกัน โดยมีคำนำหน้า test_
รายการจะเรียงตามตัวอักษร แต่ไม่จำเป็นต้องเรียงลำดับ คุณสามารถเพิ่มได้ทุกที่
หากคุณกำลังเพิ่มเกณฑ์มาตรฐาน ควรเพิ่มเกณฑ์มาตรฐานนั้นลงใน list_bench.txt
การทดสอบเหล่านี้มีป้ายกำกับแตกต่างกัน ( -L 'bench'
) และดำเนินการแยกกันบน CI
คุณต้องรัน cmake
อีกครั้งเพื่อให้การเปลี่ยนแปลงมีผล:
cmake ..
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ivan/nats.c/build
คุณสามารถใช้ตัวแปรสภาพแวดล้อมต่อไปนี้เพื่อมีอิทธิพลต่อพฤติกรรมของชุดทดสอบ
เมื่อรันด้วยการตรวจสอบหน่วยความจำ เวลาจะเปลี่ยนไปและประสิทธิภาพโดยรวมช้าลง ตัวแปรต่อไปนี้ช่วยให้ชุดทดสอบสามารถปรับค่าบางส่วนที่ใช้ในระหว่างการทดสอบ:
export NATS_TEST_VALGRIND=yes
บน Windows จะถูก set
แทน export
.
เมื่อรันการทดสอบในโหมดรายละเอียด ตัวแปรสภาพแวดล้อมต่อไปนี้ช่วยให้คุณเห็นเอาต์พุตของเซิร์ฟเวอร์จากภายในการทดสอบเอง หากไม่มีตัวเลือกนี้ เอาต์พุตของเซิร์ฟเวอร์จะถูกปิดเสียง:
export NATS_TEST_KEEP_SERVER_OUTPUT=yes
หากคุณต้องการเปลี่ยนชื่อปฏิบัติการเซิร์ฟเวอร์เริ่มต้น ( nats-server.exe
) หรือระบุตำแหน่งเฉพาะ ให้ใช้ตัวแปรสภาพแวดล้อมนี้:
set NATS_TEST_SERVER_EXE=c:testnats-server.exe
API สาธารณะได้รับการบันทึกโดยใช้ Doxygen
หากต้องการสร้างเอกสาร ให้ไปที่ไดเร็กทอรี doc
และพิมพ์คำสั่งต่อไปนี้:
doxygen DoxyFile.NATS.Client
หากคุณสลับการสร้าง Streaming API และเอกสารประกอบไม่ตรงกับสิ่งที่ถูกสร้างขึ้นอีกต่อไป คุณสามารถอัปเดตเอกสารประกอบได้โดยการสลับแฟล็กการสร้าง NATS_UPDATE_DOC
และสร้างเอกสารประกอบใหม่
จากไดเร็กทอรี build:
cmake .. -DNATS_UPDATE_DOC=ON
make
cd /doc
doxygen DoxyFile.NATS.Client
เอกสารที่สร้างขึ้นจะอยู่ในไดเร็กทอรี html
หากต้องการดูเอกสารประกอบ ให้ชี้เบราว์เซอร์ของคุณไปที่ไฟล์ index.html
ในไดเร็กทอรีนั้น
ไปที่นี่เพื่อดูเอกสารออนไลน์
ซอร์สโค้ดยังได้รับการบันทึกไว้ค่อนข้างมาก
ส่วนนี้แสดงรายการการเปลี่ยนแปลงที่สำคัญ เช่น ประกาศการเลิกใช้งาน ฯลฯ...
2.0.0
เวอร์ชันนี้แนะนำแนวคิดด้านความปลอดภัยที่ใช้โดย NATS Server 2.0.0
และดังนั้นจึงสอดคล้องกับเวอร์ชันของเซิร์ฟเวอร์ มีการเปิดตัว API ใหม่ แต่การเปลี่ยนแปลงที่สำคัญที่สุดคือพฤติกรรมเริ่มต้นใหม่กับการเชื่อมต่อ TLS:
เมื่อสร้างการเชื่อมต่อที่ปลอดภัย ชื่อโฮสต์ของใบรับรองเซิร์ฟเวอร์จะได้รับการยืนยันเสมอ ไม่ว่าผู้ใช้จะเรียกใช้ natsOptions_SetExpectedHostname()
หรือไม่ นี่อาจทำให้แอปพลิเคชันที่ใช้ IP เพื่อเชื่อมต่อกับเซิร์ฟเวอร์ที่มีเพียงชื่อโฮสต์ในใบรับรองเสียหายได้ ซึ่งสามารถแก้ไขได้โดยการเปลี่ยนแอปพลิเคชันของคุณให้ใช้ชื่อโฮสต์ใน URL หรือใช้ natsOptions_SetExpectedHostname()
หากไม่สามารถทำได้ คุณสามารถคืนค่าลักษณะการทำงานเก่าได้โดยการสร้างไลบรารีโดยปิดใช้งานลักษณะการทำงานใหม่ ดู #tls-support สำหรับข้อมูลเพิ่มเติม
พื้นที่เก็บข้อมูลนี้ใช้เพื่อรวมไลบรารีที่คอมไพล์แล้วของ libprotobuf-c สำหรับ macOS, Linux และ Windows พร้อมกับไฟล์ส่วนหัว (ในไดเร็กทอรี /pbuf
) ขณะนี้เราได้ลบไดเร็กทอรีนี้แล้ว และต้องการให้ผู้ใช้ติดตั้งไลบรารี libprotobuf-c แยกต่างหาก ดูคำแนะนำในการสร้างเพื่อระบุตำแหน่งของห้องสมุดหาก CMake ไม่พบโดยตรง
1.8.0
natsConnStatus
นำหน้าด้วย NATS_CONN_STATUS_
หากแอปพลิเคชันของคุณไม่ได้ใช้การอ้างอิงถึงค่าดั้งเดิมใดๆ เช่น CONNECTED
หรือ CLOSED
ฯลฯ คุณก็ไม่จำเป็นต้องดำเนินการใดๆ หากเป็นเช่นนั้น คุณจะมีสองทางเลือก:NATS_BUILD_NO_PREFIX_CONNSTS
ซึ่งสามารถทำได้ด้วยวิธีนี้จากไดเร็กทอรี build: cmake .. -DNATS_BUILD_NO_PREFIX_CONNSTS=ON
ไดเร็กทอรี examples/getstarted
มีชุดตัวอย่างง่ายๆ ที่ใช้งานได้เต็มรูปแบบแต่ก็เรียบง่ายมาก เป้าหมายคือการแสดงให้เห็นว่าการใช้งาน API นั้นง่ายเพียงใด
ชุดตัวอย่างที่ซับซ้อนมากขึ้นจะอยู่ในไดเร็กทอรี examples/
และยังสามารถใช้เพื่อเปรียบเทียบไลบรารีไคลเอ็นต์ได้ด้วย
โปรดทราบว่าเพื่อความง่าย จะไม่มีการตรวจสอบข้อผิดพลาดที่นี่
natsConnection * nc = NULL ;
natsSubscription * sub = NULL ;
natsMsg * msg = NULL ;
// Connects to the default NATS Server running locally
natsConnection_ConnectTo ( & nc , NATS_DEFAULT_URL );
// Connects to a server with username and password
natsConnection_ConnectTo ( & nc , "nats://ivan:secret@localhost:4222" );
// Connects to a server with token authentication
natsConnection_ConnectTo ( & nc , "nats://myTopSecretAuthenticationToken@localhost:4222" );
// Simple publisher, sending the given string to subject "foo"
natsConnection_PublishString ( nc , "foo" , "hello world" );
// Publish binary data. Content is not interpreted as a string.
char data [] = { 1 , 2 , 0 , 4 , 5 };
natsConnection_Publish ( nc , "foo" , ( const void * ) data , 5 );
// Simple asynchronous subscriber on subject foo, invoking message
// handler 'onMsg' when messages are received, and not providing a closure.
natsConnection_Subscribe ( & sub , nc , "foo" , onMsg , NULL );
// Simple synchronous subscriber
natsConnection_SubscribeSync ( & sub , nc , "foo" );
// Using a synchronous subscriber, gets the first message available, waiting
// up to 1000 milliseconds (1 second)
natsSubscription_NextMsg ( & msg , sub , 1000 );
// Destroy any message received (asynchronously or synchronously) or created
// by your application. Note that if 'msg' is NULL, the call has no effect.
natsMsg_Destroy ( msg );
// Unsubscribing
natsSubscription_Unsubscribe ( sub );
// Destroying the subscription (this will release the object, which may
// result in freeing the memory). After this call, the object must no
// longer be used.
natsSubscription_Destroy ( sub );
// Publish requests to the given reply subject:
natsConnection_PublishRequestString ( nc , "foo" , "bar" , "help!" );
// Sends a request (internally creates an inbox) and Auto-Unsubscribe the
// internal subscriber, which means that the subscriber is unsubscribed
// when receiving the first response from potentially many repliers.
// This call will wait for the reply for up to 1000 milliseconds (1 second).
natsConnection_RequestString ( & reply , nc , "foo" , "help" , 1000 );
// Closing a connection (but not releasing the connection object)
natsConnection_Close ( nc );
// When done with the object, free the memory. Note that this call
// closes the connection first, in other words, you could have simply
// this call instead of natsConnection_Close() followed by the destroy
// call.
natsConnection_Destroy ( nc );
// Message handler
void
onMsg ( natsConnection * nc , natsSubscription * sub , natsMsg * msg , void * closure )
{
// Prints the message, using the message getters:
printf ( "Received msg: %s - %.*sn" ,
natsMsg_GetSubject ( msg ),
natsMsg_GetDataLength ( msg ),
natsMsg_GetData ( msg ));
// Don't forget to destroy the message!
natsMsg_Destroy ( msg );
}
การสนับสนุน JetStream เริ่มต้นด้วยเวอร์ชัน v3.0.0
ของไลบรารีและ NATS Server v2.2.0+
แม้ว่าการรับรหัสข้อผิดพลาดเฉพาะของ JetStream ต้องใช้เซิร์ฟเวอร์ในเวอร์ชัน v2.3.0+
ตัวเลือกการกำหนดค่าบางอย่างใช้งานได้ตั้งแต่เวอร์ชัน v2.3.3
เท่านั้น ดังนั้นเราขอแนะนำให้คุณใช้ NATS Server รุ่นล่าสุดเพื่อประสบการณ์การใช้งานที่ดียิ่งขึ้น
ดูตัวอย่างที่ชื่อ js-xxx.c
ในไดเร็กทอรี examples
เพื่อดูตัวอย่างวิธีใช้ API ออบเจ็กต์และ API ใหม่ได้รับการบันทึกไว้อย่างครบถ้วนในเอกสารออนไลน์
// Connect to NATS
natsConnection_Connect ( & conn , opts );
// Initialize and set some JetStream options
jsOptions jsOpts ;
jsOptions_Init ( & jsOpts );
jsOpts . PublishAsync . MaxPending = 256 ;
// Create JetStream Context
natsConnection_JetStream ( & js , conn , & jsOpts );
// Simple Stream Publisher
js_Publish ( & pa , js , "ORDERS.scratch" , ( const void * ) "hello" , 5 , NULL , & jerr );
// Simple Async Stream Publisher
for ( i = 0 ; i < 500 ; i ++ )
{
js_PublishAsync ( js , "ORDERS.scratch" , ( const void * ) "hello" , 5 , NULL );
}
// Wait for up to 5 seconds to receive all publish acknowledgments.
jsPubOptions_Init ( & jsPubOpts );
jsPubOpts . MaxWait = 5000 ;
js_PublishAsyncComplete ( js , & jsPubOpts );
// One can get the list of all pending publish async messages,
// to either resend them or simply destroy them.
natsMsgList pending ;
s = js_PublishAsyncGetPendingList ( & pending , js );
if ( s == NATS_OK )
{
int i ;
for ( i = 0 ; i < pending . Count ; i ++ )
{
// There could be a decision to resend these messages or not.
if ( your_decision_to_resend ( pending . Msgs [ i ]))
{
// If the call is successful, pending.Msgs[i] will be set
// to NULL so destroying the pending list will not destroy
// this message since the library has taken ownership back.
js_PublishMsgAsync ( js , & ( pending . Msgs [ i ]), NULL );
}
}
// Destroy the pending list object and all messages still in that list.
natsMsgList_Destroy ( & pending );
}
// To create an asynchronous ephemeral consumer
js_Subscribe ( & sub , js , "foo" , myMsgHandler , myClosure , & jsOpts , NULL , & jerr );
// Same but use a subscription option to ask the callback to not do auto-ack.
jsSubOptions so ;
jsSubOptions_Init ( & so );
so . ManualAck = true;
js_Subscribe ( & sub , js , "foo" , myMsgHandler , myClosure , & jsOpts , & so , & jerr );
// Or to bind to an existing specific stream/durable:
jsSubOptions_Init ( & so );
so . Stream = "MY_STREAM" ;
so . Consumer = "my_durable" ;
js_Subscribe ( & sub , js , "foo" , myMsgHandler , myClosure , & jsOpts , & so , & jerr );
// Synchronous subscription:
js_SubscribeSync ( & sub , js , "foo" , & jsOpts , & so , & jerr );
jsStreamConfig cfg ;
// Connect to NATS
natsConnection_Connect ( & conn , opts );
// Create JetStream Context
natsConnection_JetStream ( & js , conn , NULL );
// Initialize the configuration structure.
jsStreamConfig_Init ( & cfg );
// Provide a name
cfg . Name = "ORDERS" ;
// Array of subjects and its size
cfg . Subjects = ( const char * [ 1 ]){ "ORDERS.*" };
cfg . SubjectsLen = 1 ;
// Create a Stream. If you are not interested in the returned jsStreamInfo object,
// you can pass NULL.
js_AddStream ( NULL , js , & cfg , NULL , & jerr );
// Update a Stream
cfg . MaxBytes = 8 ;
js_UpdateStream ( NULL , js , & cfg , NULL , & jerr );
// Delete a Stream
js_DeleteStream ( js , "ORDERS" , NULL , & jerr );
คุณสมบัติทดลอง! เราขอสงวนสิทธิ์ในการเปลี่ยนแปลง API โดยไม่จำเป็นต้องกระทบกับเวอร์ชันหลักของไลบรารี
ที่เก็บ KeyValue เป็นมุมมองที่เป็นรูปธรรมโดยยึดตาม JetStream ที่เก็บข้อมูลคือสตรีมและคีย์คือหัวข้อภายในสตรีมนั้น
คุณสมบัติบางอย่างต้องใช้ NATS Server v2.6.2
ดังนั้นเราขอแนะนำให้คุณใช้ NATS Server รุ่นล่าสุดเพื่อประสบการณ์ที่ดียิ่งขึ้น
ออบเจ็กต์และ API ใหม่ได้รับการบันทึกไว้อย่างครบถ้วนในเอกสารออนไลน์
ตัวอย่างวิธีสร้างที่เก็บ KeyValue:
jsCtx * js = NULL ;
kvStore * kv = NULL ;
kvConfig kvc ;
// Assume we got a JetStream context in `js`...
kvConfig_Init ( & kvc );
kvc . Bucket = "KVS" ;
kvc . History = 10 ;
s = js_CreateKeyValue ( & kv , js , & kvc );
// Do some stuff...
// This is to free the memory used by `kv` object,
// not delete the KeyValue store in the server
kvStore_Destroy ( kv );
นี่แสดงวิธีการ "ผูก" กับสิ่งที่มีอยู่:
jsCtx * js = NULL ;
kvStore * kv = NULL ;
// Assume we got a JetStream context in `js`...
s = js_KeyValue ( & kv , ks , "KVS" );
// Do some stuff...
// This is to free the memory used by `kv` object,
// not delete the KeyValue store in the server
kvStore_Destroy ( kv );
นี่คือวิธีการลบที่เก็บ KeyValue ในเซิร์ฟเวอร์:
jsCtx * js = NULL ;
// Assume we got a JetStream context in `js`...
s = js_DeleteKeyValue ( js , "KVS" );
นี่คือวิธีการใส่ค่าให้กับคีย์ที่กำหนด:
kvStore * kv = NULL ;
uint64_t rev = 0 ;
// Assume we got a kvStore...
s = kvStore_PutString ( & rev , kv , "MY_KEY" , "my value" );
// If the one does not care about getting the revision, pass NULL:
s = kvStore_PutString ( NULL , kv , "MY_KEY" , "my value" );
ด้านบนจะใส่ค่าให้กับคีย์ที่กำหนด แต่หากต้องการให้แน่ใจว่าค่านั้นถูกวางไว้สำหรับคีย์เฉพาะในกรณีที่ไม่เคยมีมาก่อน เราจะเรียก:
// Same note than before: if "rev" is not needed, pass NULL:
s = kvStore_CreateString ( & rev , kv , "MY_KEY" , "my value" );
เราสามารถอัปเดตคีย์ได้หากการแก้ไขครั้งล่าสุดในเซิร์ฟเวอร์ตรงกับการแก้ไขที่ส่งไปยัง API นี้:
// This would update the key "MY_KEY" with the value "my updated value" only if the current revision (sequence number) for this key is 10.
s = kvStore_UpdateString ( & rev , kv , "MY_KEY" , "my updated value" , 10 );
นี่คือวิธีการรับกุญแจ:
kvStore * kv = NULL ;
kvEntry * e = NULL ;
// Assume we got a kvStore...
s = kvStore_Get ( & e , kv , "MY_KEY" );
// Then we can get some fields from the entry:
printf ( "Key value: %sn" , kvEntry_ValueString ( e ));
// Once done with the entry, we need to destroy it to release memory.
// This is NOT deleting the key from the server.
kvEntry_Destroy ( e );
นี่คือวิธีการล้างข้อมูลคีย์:
kvStore * kv = NULL ;
// Assume we got a kvStore...
s = kvStore_Purge ( kv , "MY_KEY" );
สิ่งนี้จะลบรหัสในเซิร์ฟเวอร์:
kvStore * kv = NULL ;
// Assume we got a kvStore...
s = kvStore_Delete ( kv , "MY_KEY" );
วิธีสร้าง "ผู้เฝ้าดู" สำหรับคีย์ที่กำหนด:
kvWatcher * w = NULL ;
kvWatchOptions o ;
// Assume we got a kvStore...
// Say that we are not interested in getting the
// delete markers...
// Initialize a kvWatchOptions object:
kvWatchOptions_Init ( & o );
o . IgnoreDeletes = true;
// Create the watcher
s = kvStore_Watch ( & w , kv , "foo.*" , & o );
// Check for error..
// Now get updates:
while ( some_condition )
{
kvEntry * e = NULL ;
// Wait for the next update for up to 5 seconds
s = kvWatcher_Next ( & e , w , 5000 );
// Do something with the entry...
// Destroy to release memory
kvEntry_Destroy ( e );
}
// When done with the watcher, it needs to be destroyed to release memory:
kvWatcher_Destroy ( w );
หากต้องการรับประวัติของคีย์:
kvEntryList l ;
int i ;
// The list is defined on the stack and will be initilized/updated by this call:
s = kvStore_History ( & l , kv , "MY_KEY" , NULL );
for ( i = 0 ; i < l . Count ; i ++ )
{
kvEntry * e = l . Entries [ i ];
// Do something with the entry...
}
// When done with the list, call this to free entries and the content of the list.
kvEntryList_Destroy ( & l );
// In order to set a timeout to get the history, we need to do so through options:
kvWatchOptions o ;
kvWatchOptions_Init ( & o );
o . Timeout = 5000 ; // 5 seconds.
s = kvStore_History ( & l , kv , "MY_KEY" , & o );
นี่คือวิธีที่คุณจะได้รับกุญแจของที่ฝากข้อมูล:
kvKeysList l ;
int i ;
// If no option is required, pass NULL as the last argument.
s = kvStore_Keys ( & l , kv , NULL );
// Check error..
// Go over all keys:
for ( i = 0 ; i < l . Count ; i ++ )
printf ( "Key: %sn" , l . Keys [ i ]);
// When done, list need to be destroyed.
kvKeysList_Destroy ( & l );
// If option need to be specified:
kvWatchOptions o ;
kvWatchOptions_Init ( & o );
o . Timeout = 5000 ; // 5 seconds.
s = kvStore_Keys ( & l , kv , & o );
ส่วนหัวจะพร้อมใช้งานเมื่อเชื่อมต่อกับเซิร์ฟเวอร์ในเวอร์ชัน 2.2.0+
มีลักษณะคล้ายกับส่วนหัว http อย่างใกล้ชิด เป็นแผนผังของคู่คีย์/ค่า โดยค่าจะเป็นอาร์เรย์ของสตริง
ส่วนหัวอนุญาตให้ผู้ใช้เพิ่มข้อมูลเมตาเกี่ยวกับข้อความโดยไม่กระทบต่อเพย์โหลดข้อความ
โปรดทราบว่าหากแอปพลิเคชันพยายามส่งข้อความที่มีส่วนหัวเมื่อเชื่อมต่อกับเซิร์ฟเวอร์ที่ไม่เข้าใจ การโทรเผยแพร่จะส่งคืนข้อผิดพลาด NATS_NO_SERVER_SUPPORT
มี API ที่ต้องทราบว่าเซิร์ฟเวอร์เชื่อมต่อกับรองรับส่วนหัวหรือไม่:
natsStatus s = natsConnection_HasHeaderSupport ( conn );
if ( s == NATS_NO_SERVER_SUPPORT )
// deal with server not supporting this feature.
หากเซิร์ฟเวอร์เข้าใจส่วนหัวแต่กำลังจะส่งข้อความไปยังไคลเอนต์ที่ไม่เข้าใจ ส่วนหัวจะถูกตัดออกเพื่อให้ไคลเอนต์รุ่นเก่ายังคงสามารถรับข้อความได้ สิ่งสำคัญคือต้องมีไคลเอ็นต์และเซิร์ฟเวอร์ทั้งหมดเป็นเวอร์ชันที่รองรับส่วนหัว หากแอปพลิเคชันต้องใช้ส่วนหัว
สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับ API ส่วนหัว โปรดดูตัวอย่าง: examples/getstarted/headers.c
*
wildcard ตรงกับโทเค็นใดๆ ในทุกระดับของหัวเรื่อง:
natsConnection_Subscribe ( & sub , nc , "foo.*.baz" , onMsg , NULL );
สมาชิกรายนี้จะได้รับข้อความที่ส่งไปที่:
อย่างไรก็ตาม มันจะไม่ได้รับข้อความเมื่อ:
>
wildcard ตรงกับความยาวของความล้มเหลวของหัวเรื่อง และต้องเป็นโทเค็นสุดท้ายเท่านั้น
natsConnection_Subscribe ( & sub , nc , "foo.>" , onMsg , NULL );
สมาชิกรายนี้จะได้รับข้อความใดๆ ที่ส่งไปที่:
อย่างไรก็ตาม มันจะไม่ได้รับข้อความที่ส่งเมื่อ:
การเผยแพร่ในหัวข้อนี้จะทำให้สมาชิกทั้งสองรายข้างต้นได้รับข้อความ:
natsConnection_PublishString ( nc , "foo.bar.baz" , "got it?" );
การสมัครสมาชิกทั้งหมดที่มีชื่อคิวเดียวกันจะสร้างกลุ่มคิว แต่ละข้อความจะถูกส่งไปยังผู้สมัครสมาชิกเพียงรายเดียวต่อกลุ่มคิว โดยใช้ซีเมติกส์ของคิว คุณสามารถมีกลุ่มคิวได้มากเท่าที่คุณต้องการ สมาชิกปกติจะยังคงทำงานต่อไปตามที่คาดไว้
natsConnection_QueueSubscribe ( & sub , nc , "foo" , "job_workers" , onMsg , NULL );
(โปรดทราบว่าไลบรารีจำเป็นต้องสร้างด้วยการสนับสนุน TLS ซึ่งเป็นค่าเริ่มต้น เพื่อให้ API เหล่านี้ทำงานได้ โปรดดูบทสร้างเกี่ยวกับวิธีการสร้างโดยใช้หรือไม่มี TLS สำหรับรายละเอียดเพิ่มเติม)
การเชื่อมต่อ SSL/TLS ได้รับการกำหนดค่าผ่านการใช้ natsOptions
ขึ้นอยู่กับระดับความปลอดภัยที่คุณต้องการ อาจทำได้ง่ายเพียงแค่ตั้งค่าบูลีนที่ปลอดภัยเป็นจริงในการเรียก natsOptions_SetSecure()
แม้ว่าจะมีความปลอดภัยเต็มรูปแบบ (ไคลเอ็นต์ตรวจสอบใบรับรองเซิร์ฟเวอร์ และเซิร์ฟเวอร์ที่ต้องการใบรับรองไคลเอ็นต์) การตั้งค่าเกี่ยวข้องกับการเรียกเพียงไม่กี่ครั้ง
// Here is the minimum to create a TLS/SSL connection:
// Create an options object.
natsOptions_Create ( & opts );
// Set the secure flag.
natsOptions_SetSecure ( opts , true);
// You may not need this, but suppose that the server certificate
// is self-signed and you would normally provide the root CA, but
// don't want to. You can disable the server certificate verification
// like this:
natsOptions_SkipServerVerification ( opts , true);
// Connect now...
natsConnection_Connect ( & nc , opts );
// That's it! On success you will have a secure connection with the server!
(...)
// This example shows what it takes to have a full SSL configuration,
// including server expected's hostname, root CA, client certificates
// and specific ciphers to use.
// Create an options object.
natsOptions_Create ( & opts );
// Set the secure flag.
natsOptions_SetSecure ( opts , true);
// For a server with a trusted chain built into the client host,
// simply designate the server name that is expected. Without this
// call, the server certificate is still verified, but not the
// hostname.
natsOptions_SetExpectedHostname ( opts , "localhost" );
// Instead, if you are using a self-signed cert and need to load in the CA.
natsOptions_LoadCATrustedCertificates ( opts , caCertFileName );
// If the server requires client certificates, provide them along with the
// private key, all in one call.
natsOptions_LoadCertificatesChain ( opts , certChainFileName , privateKeyFileName );
// You can also specify preferred ciphers if you want.
natsOptions_SetCiphers ( opts , "-ALL:HIGH" );
// Then simply pass the options object to the connect call:
natsConnection_Connect ( & nc , opts );
// That's it! On success you will have a secure connection with the server!