مسجپک encoding/msgpack
قالب دودویی و فشردهی MessagePack برای مقدارهای پویا.
واردسازی کدگذاری.مسجپک
MessagePack همان دادهی جیسون را به شکل دودویی و کوتاهتر نگه میدارد و خواندنش سریعتر است؛ برای پیامهای میان سرویسها، مدخلهای حافظهی نهان و RPC مناسب است. این بسته یک مقدار را با سریال سازی به یک فشرده سازی.بافر بایت تبدیل میکند و با واسریال سازی (یا واسریال سازی بایتها برای حافظهی خام) آن را برمیگرداند. خطاها در یک خطای کدگذاری میرسند.
وقتی هر دو طرف برنامهاند و اندازه یا سرعت مهم است، آن را به جیسون ترجیح دهید؛ وقتی آدمها داده را میخوانند یا مرورگر آن را مصرف میکند، جیسون را نگه دارید. برای چینش دودویی ثابتی که خودتان تعریف کردهاید، مثل سرآیند یک پرونده، فیلدها را مستقیم با دودویی بنویسید؛ و برای طرحوارههایی که میان زبانها مشترکاند، پروتوباف.
مقدارها چطور نوشته میشوند
| مقدار | MessagePack |
|---|---|
| تهی، منطقی | nil، true/false |
| صحیح | کوچکترین قالب عدد صحیحی که جا شود، از یک تا ۸ بایت |
| اعشاری | همیشه float64 (۹ بایت)؛ float32 خوانده میشود ولی هرگز نوشته نمیشود |
| رشته | بسته به طول، fixstr، str8، str16 یا str32 |
| آرایه، شیء | fixarray/array16/array32 و fixmap/map16/map32 با کلیدهای رشتهای |
اشتباههای رایج
- نوعهای
binوextپشتیبانی نمیشوند. دادهای از کتابخانهای دیگر که بایتها را به شکلbinیا مهر زمانی را به شکلextنگه دارد، بانوع سفارشیشکست میخورد. رشتهها در نخستین بایت صفر تمام میشوند، پس دادهی دودویی را در رشته هم نمیشود فرستاد؛ اول آن را Base64 کنید. - کلیدهای نگاشت باید رشته باشند. نگاشتی با کلیدهای عددی، که برخی کتابخانههای دیگر مینویسند، طوری خوانده میشود که همهی کلیدها
""میشوند و مدخلها روی هم مینشینند. - بایتهای پس از مقدار نادیده گرفته میشوند.
واسریال سازییک مقدار میخواند و نمیگوید بعدش چه آمده یا چند بایت مصرف کرده، پس نمیتوانید چند پیام را از یک بافر بخوانید. هر پیام را خودتان قاببندی کنید، مثلاً با طولی ۴ بایتی در جلوی آن. - میان فراخوانیها خطا را از نو بسازید. اگر
خطای کدگذاریای که میدهید از قبل خطا داشته باشد،واسریال سازیبیدرنگ تهی برمیگرداند. - عددهای بزرگتر از
i64(یکuint64بیش از 9223372036854775807) دور میزنند و منفی میشوند.
راهنما: چقدر کوچکتر است؟
مسجپک نقلقولها، دونقطهها و ویرگولهای جیسون را کنار میگذارد و عددها و طولها را با کمترین بایت ممکن نگه میدارد. برای رکوردهایی با کلیدهای کوتاه و عددهای کوچک، معمولاً به نصف یا دوسوم جیسون فشرده میرسد. جیسون را یک بار به یک مقدار کدگشایی کنید و سریال سازی آن را به شکل مسجپک مینویسد.
واردسازی کدگذاری.مسجپک
واردسازی کدگذاری.جیسون
واردسازی کدگذاری.مقدار
واردسازی کدگذاری.خطای کدگذاری
واردسازی فشرده سازی
تابع ریشه:
متن := `[{"id": 1, "name": "tea", "price": 120, "stock": true},
{"id": 2, "name": "coffee", "price": 90, "stock": true},
{"id": 3, "name": "cocoa", "price": 75, "stock": false}]`
ناپایا خطا := خطای کدگذاری.بدون خطا()
ردیفها := جیسون.کدگشایی(متن، خطا)
فشرده := جیسون.کدگذاری پیش فرض(ردیفها)
بستهبندی := مسجپک.سریال سازی(ردیفها)
سرچاپ "بایتهای جیسون: "، فشرده.طول()
سرچاپ "بایتهای مسجپک: "، فشرده سازی.طول بافر(بستهبندی)
برگشتی := مسجپک.واسریال سازی(بستهبندی، خطا)
سرچاپ "همان داده:"، مقدار.یکسان است(ردیفها، برگشتی)، "خطا:"، خطای کدگذاری.خطا است(خطا)
پایانکلیدها هنوز در هر رکورد کامل نوشته میشوند، پس نامهای بلند کلید همانقدر هزینه دارند که در جیسون. اگر اندازه از این هم مهمتر است، بافر را با بستهی فشرده سازی هم فشرده کنید.
راهنما: بایتها چه شکلیاند
هر مقدار با یک بایت نوع شروع میشود. عددهای صحیح کوچک از ۰ تا ۱۲۷ یک بایتاند و بزرگترها نشانهای مثل cc (یک بایت پس از آن) یا ce (چهار بایت پس از آن) میگیرند. رشتهها، آرایهها و نگاشتهای کوتاه طولشان را در بایت اول دارند: a2 رشتهای ۲ بایتی است، 92 آرایهای با ۲ عضو و 81 نگاشتی با یک جفت.
واردسازی کدگذاری.مسجپک
واردسازی کدگذاری.مقدار
واردسازی فشرده سازی
تابع شانزدهی(م: مقدار.مقدار): رشته:
رقمها := "0123456789abcdef"
ناپایا ب := مسجپک.سریال سازی(م)
ناپایا خروجی := ""
تکرار فشرده سازی.طول بافر(ب) در ای:
ایکس := فشرده سازی.دریافت بایت(ب، ای)
اگر ای > ۰:
خروجی = خروجی + " "
پایان
خروجی = خروجی + رقمها.زیررشته(ایکس / ۱۶، ۱) + رقمها.زیررشته(ایکس % ۱۶، ۱)
پایان
فشرده سازی.آزادسازی بافر(ب)
برگشت خروجی
پایان
تابع ریشه:
سرچاپ "5 "، شانزدهی(مقدار.مقدار صحیح(۵))
سرچاپ "-1 "، شانزدهی(مقدار.مقدار صحیح(-۱))
سرچاپ "200 "، شانزدهی(مقدار.مقدار صحیح(۲۰۰))
سرچاپ "70000 "، شانزدهی(مقدار.مقدار صحیح(۷۰۰۰۰))
سرچاپ "true "، شانزدهی(مقدار.مقدار منطقی(درست))
سرچاپ "null "، شانزدهی(مقدار.مقدار تهی())
سرچاپ "1.5 "، شانزدهی(مقدار.مقدار اعشاری(۱.۵))
سرچاپ "\"hi\" "، شانزدهی(مقدار.مقدار رشته("hi"))
ناپایا آرایه := مقدار.آرایه جدید()
مقدار.افزودن به آرایه(آرایه، مقدار.مقدار صحیح(۱))
مقدار.افزودن به آرایه(آرایه، مقدار.مقدار صحیح(۲))
سرچاپ "[1, 2] "، شانزدهی(آرایه)
ناپایا شیء := مقدار.شیء جدید()
مقدار.تنظیم کلید(شیء، "a"، مقدار.مقدار صحیح(۱))
سرچاپ "{\"a\": 1}"، شانزدهی(شیء)
پایانبرنامه بافر را بایت به بایت با فشرده سازی.دریافت بایت میخواند. تبدیل بافر به رشته در اینجا کار نمیکرد: 70000 یک بایت صفر دارد و رشته در نخستین صفر تمام میشود. دادهی مسجپک را در بافر بایت خودش نگه دارید، یا هر جا متن لازم دارید از بافر به پایه۶۴ استفاده کنید.
راهنما: ساختارها در حافظهی نهان
حافظهی نهانی مثل ردیس بایت نگه میدارد و بایتهای مسجپک زودتر از جیسون خوانده میشوند. برای یک ساختار، در رفت و برگشت از جیسون بگذرید: جیسون.سریال سازی و جیسون.کدگشایی مقداری برای بستهبندی میدهند و جیسون.واسریال سازی ساختار را از مقدار بازشده پر میکند. اینجا یک نگاشت جای حافظهی نهان را گرفته است.
واردسازی کدگذاری.مسجپک
واردسازی کدگذاری.جیسون
واردسازی کدگذاری.خطای کدگذاری
واردسازی فشرده سازی
ساختار نشست:
@جیسون "user"
همگانی کاربر: رشته = ""
@جیسون "role"
همگانی نقش: رشته = ""
@جیسون "visits"
همگانی بازدید: صحیح = ۰
پایان
تابع ذخیره(نهان &: نگاشت<رشته، فشرده سازی.بافر بایت>، کلید: رشته، ن: نشست):
ناپایا خطا := خطای کدگذاری.بدون خطا()
م := جیسون.کدگشایی(جیسون.سریال سازی(ن)، خطا)
نهان.درج(کلید، مسجپک.سریال سازی(م))
پایان
تابع بارگذاری(نهان: نگاشت<رشته، فشرده سازی.بافر بایت>، کلید: رشته، خروجی &: نشست): منطقی:
اگر وارونه نهان.دارد(کلید):
برگشت نادرست
پایان
ناپایا خطا := خطای کدگذاری.بدون خطا()
م := مسجپک.واسریال سازی(نهان.بگیر(کلید)، خطا)
اگر خطای کدگذاری.خطا است(خطا):
برگشت نادرست
پایان
برگشت جیسون.واسریال سازی(جیسون.کدگذاری پیش فرض(م)، خروجی، خطا)
پایان
تابع ریشه:
ناپایا نهان := نگاشت {} برگردان نگاشت<رشته، فشرده سازی.بافر بایت>
ذخیره(نهان، "session:9f2"، نشست { کاربر = "sara"، نقش = "admin"، بازدید = ۱۲ })
ناپایا ن := نشست {}
اگر بارگذاری(نهان، "session:9f2"، ن):
سرچاپ "پیدا شد:"، ن.کاربر، ن.نقش، ن.بازدید
پایان
سرچاپ "کلید نبوده بارگذاری شد:"، بارگذاری(نهان، "session:000"، ن)
پایانبرای یک حافظهی نهان واقعی، ب.data و ب.len را به شکل مقدار دودویی به کتابخانهی کارخواه بدهید و آنچه برمیگردد را با واسریال سازی بایتها کدگشایی کنید.
راهنما: بافر خراب، بریده یا بیگانه
خواندن از شبکه ممکن است نیمهکاره بماند و برنامههای دیگر ممکن است بخشهایی از MessagePack را به کار ببرند که این بسته نمیخواند. هم واسریال سازی و هم واسریال سازی بایتها بافری را که وسط یک مقدار تمام شود با نوع اتمام ناگهانی گزارش میکنند، پس میتوانید «منتظر بایتهای بیشتر بمان» را از دادهای که بهکل نادرست است جدا کنید.
واردسازی کدگذاری.مسجپک
واردسازی کدگذاری.مقدار
واردسازی کدگذاری.خطای کدگذاری
واردسازی فشرده سازی
تابع ریشه:
ناپایا م := مقدار.شیء جدید()
مقدار.تنظیم کلید(م، "name"، مقدار.مقدار رشته("salam"))
ب := مسجپک.سریال سازی(م)
ناپایا خطا := خطای کدگذاری.بدون خطا()
کامل := مسجپک.واسریال سازی بایتها(ب.داده، ب.طول، خطا)
سرچاپ "کل بافر:"، خطای کدگذاری.خطا است(خطا)، مقدار.به رشته(مقدار.مقدار کلید(کامل، "name"))
ناپایا بریده := خطای کدگذاری.بدون خطا()
_ := مسجپک.واسریال سازی بایتها(ب.داده، ب.طول - ۳، بریده)
سرچاپ "بریده:"، خطای کدگذاری.خطا است(بریده)، بریده.نوع == خطای کدگذاری.نوع اتمام ناگهانی، بریده.پیام
ناپایا لکه := فشرده سازی.بافر بایت جدید()
فشرده سازی.افزودن بایت(لکه، 0xc4)
فشرده سازی.افزودن بایت(لکه، ۲)
فشرده سازی.افزودن بایت(لکه، 0xca)
فشرده سازی.افزودن بایت(لکه، 0xfe)
ناپایا دودویی := خطای کدگذاری.بدون خطا()
_ := مسجپک.واسریال سازی(لکه، دودویی)
سرچاپ "bin از کتابخانهای دیگر:"، دودویی.نوع == خطای کدگذاری.نوع سفارشی، دودویی.پیام
ناپایا دوتایی := فشرده سازی.کپی بافر(ب)
فشرده سازی.افزودن بایت(دوتایی، 0x2a)
ناپایا اضافه := خطای کدگذاری.بدون خطا()
نخست := مسجپک.واسریال سازی(دوتایی، اضافه)
سرچاپ "یک بایت اضافه پس از مقدار:"، خطای کدگذاری.خطا است(اضافه)، مقدار.طول شیء(نخست)، "کلید خوانده شد"
پایانحالت سوم یک مقدار bin با بایت نوع c4 است، همان چیزی که کتابخانههایی مینویسند که بایت را از رشته جدا نگه میدارند؛ با نوع سفارشی شکست میخورد. وقتی فرستنده باید با سلام حرف بزند، از او بخواهید رشته بفرستد یا بایتها را Base64 کند. حالت آخر نشان میدهد یک بایت سرگردان پس از مقدار کامل دیده نمیشود؛ برای همین جریانی از پیامها قاببندی خودش را لازم دارد.
گونهها
گزینههای مسجپک MsgpackOptions
ساختار گزینههای مسجپک| نام | انگلیسی | گونه | توضیح |
|---|---|---|---|
| قالب کوتاه رشته | use_str8 | منطقی = درست | برای رشتههای ۳۲ تا ۲۵۵ بایتی از قالب str8 استفاده شود؛ پیشفرض درست. برای خوانندههای خیلی قدیمی که str8 را نمیشناسند نادرستش کنید؛ آنوقت این رشتهها به شکل str16 نوشته میشوند. |
واردسازی کدگذاری.مسجپک
واردسازی کدگذاری.مقدار
واردسازی کدگذاری.خطای کدگذاری
واردسازی کدگذاری
واردسازی فشرده سازی
تابع ریشه:
ناپایا م := مقدار.شیء جدید()
مقدار.تنظیم کلید(م، "id"، مقدار.مقدار صحیح(۷))
مقدار.تنظیم کلید(م، "ok"، مقدار.مقدار منطقی(درست))
ب := مسجپک.سریال سازی(م)
سرچاپ فشرده سازی.طول بافر(ب)، فشرده سازی.بافر به پایه۶۴(ب)
ناپایا خ := خطای کدگذاری.بدون خطا()
ب۲ := مسجپک.واسریال سازی(ب، خ)
سرچاپ خطای کدگذاری.خطا است(خ)، مقدار.یکسان است(م، ب۲)، مقدار.به صحیح(مقدار.مقدار کلید(ب۲، "id"))
ب۳ := مسجپک.واسریال سازی بایتها(ب.داده، ب.طول، خ)
سرچاپ مقدار.یکسان است(م، ب۳)
گ := مسجپک.گزینههای مسجپک {}
سرچاپ فشرده سازی.طول بافر(مسجپک.سریال سازی سفارشی(م، گ))
سرچاپ کدگذاری.کدگذاری شانزده(فشرده سازی.بافر به رشته(مسجپک.سریال سازی(مقدار.مقدار صحیح(۵))))
پایانتابعها
سریال سازی سفارشی MarshalWith
تابع سریال سازی سفارشی(v: value.Value، opts: گزینههای مسجپک): compress.ByteBufنمونهی این مورد همراه با موارد بالاتر آمده است: encoding-msgpack-Marshal.salam
سریال سازی Marshal
تابع سریال سازی(v: value.Value): compress.ByteBufفشرده سازی.آزادسازی بافر آزاد کنید.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-msgpack-Marshal.salam
واسریال سازی بایتها UnmarshalBytes
تابع واسریال سازی بایتها(p: تهی*، n: صحیح، err &: encerr.EncodingError): value.Valuen بایت در نشانی p میخواند، برای دادهای که در بافر بایت نیست، مثل پاسخ یک کارخواه حافظهی نهان. بایتهای پس از مقدار نادیده گرفته میشوند.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-msgpack-Marshal.salam
واسریال سازی Unmarshal
تابع واسریال سازی(b: compress.ByteBuf، err &: encerr.EncodingError): value.Valuebin یا ext داشته باشد، err پر میشود. هر بار یک بدون خطا() تازه بدهید.نمونهی این مورد همراه با موارد بالاتر آمده است: encoding-msgpack-Marshal.salam