کتابخانه‌ی استاندارد · شبکه

وب‌سوکت net/websocket

اتصال دوطرفه‌ی همیشه‌باز میان مرورگر و سرور، با اتاق‌ها برای پخش پیام.

واردسازی شبکه.وب‌سوکت

وب‌سوکت اتصالی است که با یک درخواست HTTP شروع می‌شود و سپس باز می‌ماند و هر دو طرف هر وقت خواستند پیام می‌فرستند: گفتگوی زنده، اعلان، داشبورد و بازی. این بسته هر دو سر را دارد. سرور با شنود و پذیرش روی درگاه خودش اتصال می‌گیرد و کارخواه با شماره گیری وصل می‌شود؛ پذیرش امن و شماره گیری امن همین کار را روی TLS می‌کنند. شنونده‌ی خودش را دارد و به سرور اچ تی تی پی وصل نمی‌شود. برای پروتکل Socket.IO که بسیاری از برنامه‌های جاوااسکریپت به کار می‌برند (رویداد، تأیید دریافت، اتصال دوباره) از سوکت‌آیاو استفاده کنید؛ WebSocket ساده‌ی مرورگر مستقیم با همین بسته حرف می‌زند.

مفهوم‌های اصلی:

  • دریافت پیام تا رسیدن یک پیام کامل صبر می‌کند و یک پیام برمی‌گرداند؛ نوعش را با متن است، دودویی است و بسته است بسنجید. به پینگ‌ها خودکار پاسخ داده می‌شود. دریافت با مهلت حداکثر زمانی مشخص صبر می‌کند.
  • هاب اتصال‌ها را در اتاق‌ها گروه می‌کند تا یک فراخوانی به همه‌ی اعضا برسد.
  • هر اتصال را یک نخ می‌خواند. برای اداره‌ی چند کارخواه، به هر اتصال نخ خودش را بدهید.

چیزهایی که بیشتر غافلگیر می‌کنند:

  • هاب قفل ندارد. وقتی چند نخ اتصال آن را با هم به کار می‌برند، ثبت، لغو ثبت و پخش را درون یک قفل از همگام سازی بگذارید.
  • برای لغو ثبت یک نسخه از اتصال نگه دارید. وقتی طرف مقابل می‌بندد، دریافت پیام مقدار fd اتصال را پاک می‌کند و لغو ثبت با همین شماره‌ی سوکت مقایسه می‌کند؛ پس لغو ثبت با اتصال بسته‌شده چیزی را برنمی‌دارد. نسخه‌ای را که درست پس از پذیرش برداشته‌اید ثبت کنید و با همان نسخه لغو ثبت کنید.
  • متن در نخستین بایت صفر تمام می‌شود و درستی UTF-8 آن بررسی نمی‌شود. داده‌ی دودویی را دودویی بفرستید و از data و len پیام بخوانید؛ آن بافر مال اتصال است و پیام دودویی بعدی رویش می‌نویسد، پس هر چه را نگه می‌دارید رونوشت کنید.
  • سرور هر مبدئی را می‌پذیرد و زیرپروتکل یا فشرده‌سازی ندارد؛ اگر قاعده‌ای برای Origin لازم دارید خودتان hdr اتصال را بررسی کنید. قابی بزرگ‌تر از ۱۰۰ مگابایت اتصال را می‌بندد.

هر نمونه‌ی زیر یک سرور و کارخواه‌هایش را در یک برنامه اجرا می‌کند: سرور در نخی که با نخ‌ساز شروع می‌شود و روی درگاه آزادی که شنود(۰) انتخاب می‌کند. به این ترتیب بدون شبکه اجرا می‌شوند؛ در برنامه‌ی واقعی کارخواه‌ها مرورگرهایی هستند که API جاوااسکریپت WebSocket را به کار می‌برند و همین پروتکل را حرف می‌زنند.

پیام‌های JSON با نوع

وب‌سوکت متن یا بایت جابه‌جا می‌کند و ساختار با شماست. انتخاب رایج یک شیء JSON برای هر پیام با فیلد type است و حلقه‌ای در سرور که پیام را می‌خواند، به نوع نگاه می‌کند و پاسخ می‌دهد. دریافت پیام منتظر پیام بعدی می‌ماند، متن است پیام متنی را از قاب بستن یا دودویی جدا می‌کند و جیسون.رشته جیسون متن کاربر را هنگام ساختن پاسخ با دست بی‌خطر نقل‌قول می‌کند.

net-websocket-json.salam
واردسازی شبکه.وب‌سوکت
واردسازی کدگذاری.جیسون

ناپایا سرور := وب‌سوکت.سرور {}

تابع گفتگو():
    ناپایا اتصال := وب‌سوکت.پذیرش(سرور)
    ناپایا نام := ""
    تا وب‌سوکت.باز است(اتصال):
        پیام := وب‌سوکت.دریافت پیام(اتصال)
        اگر وارونه وب‌سوکت.متن است(پیام): بشکن پایان
        نوع := جیسون.دریافت(پیام.متن، "type")
        اگر نوع برابر "join":
            نام = جیسون.دریافت(پیام.متن، "name")
            _ := وب‌سوکت.ارسال متن(اتصال، `{"type": "joined", "users": 1}`)
        وگرنه نوع برابر "say":
            پاسخ := `{"type": "said", "from": ` + جیسون.رشته جیسون(نام) + `, "text": ` + جیسون.رشته جیسون(جیسون.دریافت(پیام.متن، "text")) + `}`
            _ := وب‌سوکت.ارسال متن(اتصال، پاسخ)
        وگرنه:
            _ := وب‌سوکت.ارسال متن(اتصال، `{"type": "error", "reason": "unknown type"}`)
        پایان
    پایان
    وب‌سوکت.بستن(اتصال)
پایان

تابع بپرس(ک &: وب‌سوکت.اتصال وب، درخواست: رشته): رشته:
    _ := وب‌سوکت.ارسال متن(ک، درخواست)
    برگشت وب‌سوکت.دریافت متن(ک)
پایان

تابع ریشه:
    سرور = وب‌سوکت.شنود(۰)
    نخ := نخ‌ساز(گفتگو)
    ناپایا ک := وب‌سوکت.شماره گیری("127.0.0.1"، وب‌سوکت.درگاه(سرور)، "/chat")
    پیوست := بپرس(ک، `{"type": "join", "name": "سارا"}`)
    سرچاپ جیسون.دریافت(پیوست، "type")، "کاربران:"، جیسون.دریافت عدد(پیوست، "users")
    گفته := بپرس(ک، `{"type": "say", "text": "سلام \"به همه\""}`)
    سرچاپ جیسون.دریافت(گفته، "from")، "گفت:"، جیسون.دریافت(گفته، "text")
    سرچاپ بپرس(ک، `{"type": "dance"}`)
    وب‌سوکت.بستن(ک)
    نخ‌پیوند(نخ)
    وب‌سوکت.بستن سرور(سرور)
پایان
خروجیjoined کاربران: 1 سارا گفت: سلام "به همه" {"type": "error", "reason": "unknown type"}

به نوع ناشناخته همیشه با پیام خطا پاسخ دهید و اتصال را نبندید؛ کارخواه‌هایی که بعداً ساخته می‌شوند ممکن است نوع‌هایی بفرستند که سرور قدیمی نمی‌شناسد.

اتاق‌ها با هاب

یک گفتگو یا صفحه‌ی نتیجه‌ی زنده یک پیام را به اتصال‌های زیادی می‌فرستد. یک هاب اتصال‌ها را با نام اتاق نگه می‌دارد: ثبت اتصالی را به اتاقی می‌افزاید، پخش متن را به همه‌ی اعضا می‌فرستد و می‌گوید چند نفر آن را گرفتند و اندازه اتاق اعضا را می‌شمارد. نام طبیعی اتاق همان مسیری است که کارخواه به آن وصل شده و سرور آن را در path اتصال می‌بیند.

net-websocket-rooms.salam
واردسازی شبکه.وب‌سوکت
واردسازی رشته

ناپایا سرور := وب‌سوکت.سرور {}
ناپایا هاب := وب‌سوکت.هاب جدید()

تابع پذیرنده():
    تکرار ۳:
        اتصال := وب‌سوکت.پذیرش(سرور)
        اتاق := رشته.جایگزینی(اتصال.مسیر، "/rooms/"، "")
        وب‌سوکت.ثبت(هاب، اتاق، اتصال)
    پایان
پایان

تابع ریشه:
    سرور = وب‌سوکت.شنود(۰)
    درگاه := وب‌سوکت.درگاه(سرور)
    نخ := نخ‌ساز(پذیرنده)
    ناپایا علی := وب‌سوکت.شماره گیری("127.0.0.1"، درگاه، "/rooms/news")
    ناپایا سارا := وب‌سوکت.شماره گیری("127.0.0.1"، درگاه، "/rooms/news")
    ناپایا رضا := وب‌سوکت.شماره گیری("127.0.0.1"، درگاه، "/rooms/sport")
    نخ‌پیوند(نخ)
    سرچاپ "خبر:"، وب‌سوکت.اندازه اتاق(هاب، "news")، "ورزش:"، وب‌سوکت.اندازه اتاق(هاب، "sport")
    سرچاپ "به"، وب‌سوکت.پخش(هاب، "news"، "نرخ‌ها بالا رفت")، "نفر در خبر فرستاده شد"
    سرچاپ "به"، وب‌سوکت.پخش(هاب، "sport"، "نیمه‌ی اول ۲ بر ۱")، "نفر در ورزش فرستاده شد"
    سرچاپ "علی:"، وب‌سوکت.دریافت متن(علی)
    سرچاپ "سارا:"، وب‌سوکت.دریافت متن(سارا)
    سرچاپ "رضا:"، وب‌سوکت.دریافت متن(رضا)
    سرچاپ "کسی در شطرنج نیست:"، وب‌سوکت.پخش(هاب، "chess"، "سلام")
    وب‌سوکت.بستن(علی)
    وب‌سوکت.بستن(سارا)
    وب‌سوکت.بستن(رضا)
    وب‌سوکت.بستن سرور(سرور)
پایان
خروجیخبر: 2 ورزش: 1 به 2 نفر در خبر فرستاده شد به 1 نفر در ورزش فرستاده شد علی: نرخ‌ها بالا رفت سارا: نرخ‌ها بالا رفت رضا: نیمه‌ی اول ۲ بر ۱ کسی در شطرنج نیست: 0

در سرور واقعی هر اتصال را در نخ خودش بخوانید و وقتی بسته شد لغو ثبت را صدا بزنید تا پخش به اتصال‌هایی که رفته‌اند نرسد. بخش بعد همین سرور را نشان می‌دهد.

سرور گفتگو با یک نخ برای هر اتصال

این‌جا هر نخ عضو یک اتصال را می‌پذیرد، آن را در اتاق lobby ثبت می‌کند و سپس تا بسته شدن اتصال آن را می‌خواند و هر سطر را به اتاق پخش می‌کند. چند نخ می‌توانند روی یک سرور پذیرش را صدا بزنند و هر کدام کارخواه متفاوتی می‌گیرد. هاب مشترک است، پس هر فراخوانی هاب درون یک قفل است. نخ نسخه عضویت را ثبت می‌کند، نسخه‌ای که پیش از هر دریافت پیام برداشته شده، و با همان نسخه لغو ثبت می‌کند؛ اگر خود اتصال را به کار می‌بردیم، در پایان اتاق هنوز دو عضو می‌شمرد.

net-websocket-chat-server.salam
واردسازی شبکه.وب‌سوکت
واردسازی رشته
واردسازی همگام سازی

ناپایا سرور := وب‌سوکت.سرور {}
ناپایا هاب := وب‌سوکت.هاب جدید()
ناپایا قفل := همگام سازی.قفل جدید()

تابع اعلام(متن: رشته):
    همگام سازی.قفل کردن(قفل)
    _ := وب‌سوکت.پخش(هاب، "lobby"، متن)
    همگام سازی.باز کردن قفل(قفل)
پایان

تابع عضو():
    ناپایا اتصال := وب‌سوکت.پذیرش(سرور)
    اگر وارونه وب‌سوکت.باز است(اتصال): برگشت پایان
    نام := رشته.جایگزینی(اتصال.مسیر، "/chat/"، "")
    نسخه عضویت := اتصال
    همگام سازی.قفل کردن(قفل)
    وب‌سوکت.ثبت(هاب، "lobby"، نسخه عضویت)
    همگام سازی.باز کردن قفل(قفل)
    _ := وب‌سوکت.ارسال متن(اتصال، "خوش آمدی، " + نام)
    تا وب‌سوکت.باز است(اتصال):
        پ := وب‌سوکت.دریافت پیام(اتصال)
        اگر وارونه وب‌سوکت.متن است(پ): بشکن پایان
        اعلام(نام + ": " + پ.متن)
    پایان
    همگام سازی.قفل کردن(قفل)
    وب‌سوکت.لغو ثبت(هاب، "lobby"، نسخه عضویت)
    همگام سازی.باز کردن قفل(قفل)
    اعلام(نام + " رفت")
    وب‌سوکت.بستن(اتصال)
پایان

تابع ریشه:
    سرور = وب‌سوکت.شنود(۰)
    درگاه := وب‌سوکت.درگاه(سرور)
    الف := نخ‌ساز(عضو)
    ب := نخ‌ساز(عضو)
    ناپایا سارا := وب‌سوکت.شماره گیری("127.0.0.1"، درگاه، "/chat/sara")
    سرچاپ "سارا گرفت:"، وب‌سوکت.دریافت متن(سارا)
    ناپایا رضا := وب‌سوکت.شماره گیری("127.0.0.1"، درگاه، "/chat/reza")
    سرچاپ "رضا گرفت:"، وب‌سوکت.دریافت متن(رضا)

    _ := وب‌سوکت.ارسال متن(سارا، "ناهار ساعت یک؟")
    سرچاپ "سارا گرفت:"، وب‌سوکت.دریافت متن(سارا)
    سرچاپ "رضا گرفت:"، وب‌سوکت.دریافت متن(رضا)

    وب‌سوکت.بستن(رضا)
    سرچاپ "سارا گرفت:"، وب‌سوکت.دریافت متن(سارا)
    وب‌سوکت.بستن(سارا)
    نخ‌پیوند(الف)
    نخ‌پیوند(ب)
    سرچاپ "باقی‌مانده در لابی:"، وب‌سوکت.اندازه اتاق(هاب، "lobby")
    وب‌سوکت.بستن سرور(سرور)
    همگام سازی.نابودسازی(قفل)
پایان
خروجیسارا گرفت: خوش آمدی، sara رضا گرفت: خوش آمدی، reza سارا گرفت: sara: ناهار ساعت یک؟ رضا گرفت: sara: ناهار ساعت یک؟ سارا گرفت: reza رفت باقی‌مانده در لابی: 0

یک نخ برای هر کارخواه برای صدها اتصال کافی است. برای هر کارخواهی که انتظارش را دارید یک نخ عضو راه بیندازید، یا هر نخ پس از برگشتن پذیرش نخ بعدی را بسازد تا همیشه یکی منتظر بازدیدکننده‌ی بعدی باشد.

بررسی توکن هنگام دست دادن

وب‌سوکت با یک درخواست HTTP شروع می‌شود و سرآیندهای آن در hdr اتصال می‌مانند؛ پس سرور می‌تواند پیش از اعتماد به اتصال توکن را بررسی کند. آن را با مقدار سرصفحه از اچ تی تی پی بخوانید. در سمت کارخواه شماره گیری با سربرگ سطرهای سرآیند اضافه را می‌افزاید. اتصالی که توکن درست ندارد پیامی کوتاه می‌گیرد و بسته می‌شود و کارخواه آن را به شکل پیام بستن از دریافت با مهلت می‌بیند.

net-websocket-auth.salam
واردسازی شبکه.وب‌سوکت
واردسازی شبکه.اچ تی تی پی

ناپایا سرور := وب‌سوکت.سرور {}

تابع دروازه():
    تکرار ۲:
        ناپایا اتصال := وب‌سوکت.پذیرش(سرور)
        توکن := اچ تی تی پی.مقدار سرصفحه(اتصال.سرآیندهای دست‌دهی، "authorization")
        اگر توکن برابر "Bearer sara-token":
            _ := وب‌سوکت.ارسال متن(اتصال، "سارا، خوش آمدی")
            پرسش := وب‌سوکت.دریافت متن(اتصال)
            _ := وب‌سوکت.ارسال متن(اتصال، "پرسیدی: " + پرسش)
        وگرنه:
            _ := وب‌سوکت.ارسال متن(اتصال، "شما کی هستید؟")
        پایان
        وب‌سوکت.بستن(اتصال)
    پایان
پایان

تابع امتحان(درگاه: صحیح، سرآیند اضافه: رشته):
    ناپایا ک := وب‌سوکت.شماره گیری با سربرگ("127.0.0.1"، درگاه، "/live"، سرآیند اضافه)
    سرچاپ "باز:"، وب‌سوکت.باز است(ک)، "سرور می‌گوید:"، وب‌سوکت.دریافت متن(ک)
    اگر سرآیند اضافه نابرابر "":
        _ := وب‌سوکت.ارسال متن(ک، "خبر تازه‌ای هست؟")
        سرچاپ وب‌سوکت.دریافت متن(ک)
    پایان
    پیام := وب‌سوکت.دریافت با مهلت(ک، ۲۰۰۰)
    سرچاپ "سرور بست:"، وب‌سوکت.بسته است(پیام)
پایان

تابع ریشه:
    سرور = وب‌سوکت.شنود(۰)
    نخ := نخ‌ساز(دروازه)
    امتحان(وب‌سوکت.درگاه(سرور)، "Authorization: Bearer sara-token\r\n")
    امتحان(وب‌سوکت.درگاه(سرور)، "")
    نخ‌پیوند(نخ)
    وب‌سوکت.بستن سرور(سرور)
پایان
خروجیباز: true سرور می‌گوید: سارا، خوش آمدی پرسیدی: خبر تازه‌ای هست؟ سرور بست: true باز: true سرور می‌گوید: شما کی هستید؟ سرور بست: true

مرورگرها نمی‌توانند روی وب‌سوکت سرآیند Authorization بگذارند. برای کارخواه مرورگر یک توکن کوتاه‌عمر در نشانی بگذارید، مثل /live?token=...، و به جای آن path اتصال را بررسی کنید.

صبر بدون گیر کردن: دریافت با مهلت و پینگ

کارخواهی که مدت زیادی منتظر پاسخ می‌ماند باید بداند اتصال هنوز زنده است و پراکسی‌ها اتصال‌هایی را که ساکت بمانند می‌بندند. دریافت با مهلت(اتصال، میلی‌ثانیه) حداکثر همان قدر صبر می‌کند و اگر چیزی نرسید پیامی از نوع مهلت برمی‌گرداند؛ همان لحظه وقت فرستادن پینگ فرست است. حلقه‌ی زیر منتظر گزارش یک کار می‌ماند، هر ۱۰۰ میلی‌ثانیه پینگ می‌فرستد و پس از ۵۰ دور سکوت دست می‌کشد.

net-websocket-heartbeat.salam
واردسازی شبکه.وب‌سوکت
واردسازی زمان

ناپایا سرور := وب‌سوکت.سرور {}

تابع کارگر():
    ناپایا اتصال := وب‌سوکت.پذیرش(سرور)
    زمان.خواب(۴۰۰)
    _ := وب‌سوکت.ارسال متن(اتصال، "گزارش آماده است")
    تا وب‌سوکت.باز است(اتصال):
        پیام := وب‌سوکت.دریافت پیام(اتصال)
        اگر وب‌سوکت.بسته است(پیام) یا پیام.نوع برابر وب‌سوکت.هیچ: بشکن پایان
    پایان
    وب‌سوکت.بستن(اتصال)
پایان

تابع ریشه:
    سرور = وب‌سوکت.شنود(۰)
    نخ := نخ‌ساز(کارگر)
    ناپایا ک := وب‌سوکت.شماره گیری("127.0.0.1"، وب‌سوکت.درگاه(سرور)، "/jobs/42")
    ناپایا بیکار := ۰
    ناپایا جواب := ""
    تا جواب برابر "" و بیکار کوچکتر ۵۰:
        پیام := وب‌سوکت.دریافت با مهلت(ک، ۱۰۰)
        اگر پیام.نوع برابر وب‌سوکت.مهلت:
            بیکار += ۱
            _ := وب‌سوکت.پینگ فرست(ک، "هنوز این‌جام")
        وگرنه وب‌سوکت.متن است(پیام):
            جواب = پیام.متن
        وگرنه وب‌سوکت.بسته است(پیام):
            بشکن
        پایان
    پایان
    سرچاپ "جواب:"، جواب
    سرچاپ "در انتظار پینگ فرستاد:"، بیکار بزرگتر ۰
    وب‌سوکت.بستن(ک)
    نخ‌پیوند(نخ)
    وب‌سوکت.بستن سرور(سرور)
پایان
خروجیجواب: گزارش آماده است در انتظار پینگ فرستاد: true

تابع‌های فرستادن در صورت موفقیت ۰ و وقتی اتصال از دست رفته عددی منفی برمی‌گردانند؛ پس در حلقه‌های طولانی نتیجه‌ی ارسال متن و پینگ فرست را بررسی کنید.

کدام تابع برای کدام کار

کارسرورکارخواه
باز کردنشنود، پذیرش (TLS: بارگذاری پیکربندی امن، پذیرش امن)شماره گیری، شماره گیری با سربرگ (TLS: شماره گیری امن)
فرستادنارسال متن، ارسال دودویی، پینگ فرست
گرفتندریافت پیام (صبر می‌کند)، دریافت با مهلت (با مهلت زمانی)، دریافت متن (فقط متن)
تشخیص نوع پیاممتن است، دودویی است، بسته است، پونگ است یا kind پیام
کارخواه‌های زیادهاب جدید، ثبت، پخش، لغو ثبت
بستنبستن، بستن سروربستن

گونه‌ها

سرور Server

ساختار سرور
سرور وب‌سوکت.
نامانگلیسیگونهتوضیح
توصیفگر سوکتfdصحیح۶۴ = -1شناسه‌ی سوکت.
درگاهportصحیح = 0درگاه.
net-websocket-Echo.salam
واردسازی شبکه.وب‌سوکت

ناپایا سرور := وب‌سوکت.سرور {}

تابع پاسخ‌گو():
    ناپایا ا := وب‌سوکت.پذیرش(سرور)
    تا وب‌سوکت.باز است(ا):
        پ := وب‌سوکت.دریافت پیام(ا)
        اگر وب‌سوکت.متن است(پ):
            _ := وب‌سوکت.ارسال متن(ا، "پژواک: " + پ.متن)
        وگرنه وب‌سوکت.دودویی است(پ):
            _ := وب‌سوکت.ارسال بایت دودویی(ا، پ.داده، پ.طول)
        وگرنه وب‌سوکت.بسته است(پ):
            بشکن
        پایان
    پایان
    وب‌سوکت.بستن(ا)
پایان

تابع ریشه:
    سرور = وب‌سوکت.شنود(۰)
    سرچاپ وب‌سوکت.معتبر(سرور)، وب‌سوکت.درگاه(سرور) > ۰
    ن := نخ‌ساز(پاسخ‌گو)
    ناپایا ک := وب‌سوکت.شماره گیری("127.0.0.1"، وب‌سوکت.درگاه(سرور)، "/chat")
    سرچاپ وب‌سوکت.باز است(ک)، ک.مسیر، ک.سمت کارخواه
    _ := وب‌سوکت.ارسال متن(ک، "سلام")
    سرچاپ وب‌سوکت.دریافت متن(ک)
    _ := وب‌سوکت.ارسال دودویی(ک، "abc")
    پ := وب‌سوکت.دریافت با مهلت(ک، ۲۰۰۰)
    سرچاپ پ.نوع == وب‌سوکت.دودویی، پ.طول
    _ := وب‌سوکت.پینگ فرست(ک، "p")
    پ۲ := وب‌سوکت.دریافت با مهلت(ک، ۲۰۰۰)
    سرچاپ وب‌سوکت.پونگ است(پ۲)، پ۲.نوع == وب‌سوکت.پونگ
    پ۳ := وب‌سوکت.دریافت با مهلت(ک، ۵۰)
    سرچاپ پ۳.نوع == وب‌سوکت.مهلت
    وب‌سوکت.بستن(ک)
    نخ‌پیوند(ن)
    وب‌سوکت.بستن سرور(سرور)
    سرچاپ وب‌سوکت.هیچ، وب‌سوکت.متن، وب‌سوکت.بسته، وب‌سوکت.پینگ
پایان
خروجیtrue true true /chat true پژواک: سلام true 3 true true true 0 1 8 9

اتصال وب Conn

ساختار اتصال وب
یک اتصال وب‌سوکت، در سمت سرور یا کارخواه.
نامانگلیسیگونهتوضیح
توصیفگر سوکتfdصحیح۶۴ = -1شناسه‌ی سوکت.
بازopenمنطقی = نادرستاتصال باز است.
مسیرpathرشته = ""مسیر درخواست‌شده، مثل /chat.
سمت کارخواهclientمنطقی = نادرستاین سمت کارخواه است؛ کارخواه قاب‌ها را پوشانده می‌فرستد.
بافر دریافتbufتهی*بافر دریافت.
طول بافرblenصحیح = 0طول داده‌ی بافر.
ظرفیت بافرbcapصحیح = 0ظرفیت بافر.
رمزشدهsecureمنطقی = نادرسترمزشده است.
شماره تی ال اسtls_idxصحیح = -1شناسه‌ی درونی TLS.
سرآیندهای دست‌دهیhdrرشته = ""سرآیندهای دست دادن.
متن جمع‌شدهaccرشته = ""متن پیام چندقابی در حال جمع شدن.
نوع پیام جمع‌شدهacc_kindصحیح = 0نوع پیام چندقابی.
چندقابیfragmentedمنطقی = نادرستپیام چندقابی در راه است.
بافر دودوییbinتهی*بافر پیام دودویی.
طول بافر دودوییbinlenصحیح = 0طول آن.
ظرفیت بافر دودوییbincapصحیح = 0ظرفیت آن.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

پیام Message

ساختار پیام
یک پیام دریافتی.
نامانگلیسیگونهتوضیح
نوعkindصحیح = 0نوع پیام؛ یکی از ثابت‌های بالا.
متنtextرشته = ""متن پیام متنی، بریده در نخستین بایت صفر.
دادهdataتهی*بایت‌های پیام دودویی. در بافر اتصال‌اند و پیام دودویی بعدی رویشان می‌نویسد.
طولlenصحیح = 0طول داده.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

اعضای اتاق RoomMembers

ساختار اعضای اتاق
اعضای یک اتاق.
نامانگلیسیگونهتوضیح
اتصال‌هاitemsوکتور<اتصال وب>اتصال‌ها.
net-websocket-Hub.salam
واردسازی شبکه.وب‌سوکت

ناپایا سرور := وب‌سوکت.سرور {}
ناپایا طرف‌ها := وکتور {} برگردان وکتور<وب‌سوکت.اتصال وب>

تابع پذیرنده():
    تکرار ۲:
        طرف‌ها.بیفزا(وب‌سوکت.پذیرش(سرور))
    پایان
پایان

تابع ریشه:
    سرور = وب‌سوکت.شنود(۰)
    د := وب‌سوکت.درگاه(سرور)
    ن := نخ‌ساز(پذیرنده)
    ناپایا الف := وب‌سوکت.شماره گیری("127.0.0.1"، د، "/room")
    ناپایا ب := وب‌سوکت.شماره گیری با سربرگ("127.0.0.1"، د، "/room"، "X-Name: b\r\n")
    نخ‌پیوند(ن)
    ناپایا هاب := وب‌سوکت.هاب جدید()
    هر ط در طرف‌ها:
        وب‌سوکت.ثبت(هاب، "lobby"، ط)
    پایان
    سرچاپ وب‌سوکت.اندازه اتاق(هاب، "lobby")، هاب.اتاق‌ها.اندازه()
    سرچاپ وب‌سوکت.پخش(هاب، "lobby"، "خوش آمدید")
    سرچاپ وب‌سوکت.دریافت متن(الف)، وب‌سوکت.دریافت متن(ب)
    سرچاپ وب‌سوکت.پخش دودویی(هاب، "lobby"، "xy")
    سرچاپ وب‌سوکت.دریافت پیام(الف).طول
    وب‌سوکت.لغو ثبت(هاب، "lobby"، طرف‌ها[۰])
    سرچاپ وب‌سوکت.اندازه اتاق(هاب، "lobby")
    وب‌سوکت.توقف(الف)
    وب‌سوکت.بستن(ب)
    وب‌سوکت.بستن سرور(سرور)
پایان
خروجی2 1 2 خوش آمدید خوش آمدید 2 2 1

هاب Hub

ساختار هاب
هاب: اتصال‌ها را در اتاق‌ها گروه می‌کند تا یک پیام به همه‌ی اعضای اتاق برسد؛ برای گفتگو.
نامانگلیسیگونهتوضیح
اتاق‌هاroomsنگاشت<رشته، اعضای اتاق>اتاق‌ها و اعضایشان.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Hub.salam

پایاها و متغیرها

هیچ NONE

پایا هیچ: صحیح۳۲ = 0
هیچ پیامی نیست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

متن TEXT

پایا متن: صحیح۳۲ = 1
پیام متنی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

دودویی BINARY

پایا دودویی: صحیح۳۲ = 2
پیام دودویی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

بسته CLOSE

پایا بسته: صحیح۳۲ = 8
طرف دیگر اتصال را بست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

پینگ PING

پایا پینگ: صحیح۳۲ = 9
پینگ.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

پونگ PONG

پایا پونگ: صحیح۳۲ = 10
پاسخ پینگ.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

مهلت TIMEOUT

پایا مهلت: صحیح۳۲ = 100
در مهلت پیامی نرسید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

تابع‌ها

کلید پذیرش AcceptKey

تابع کلید پذیرش(key: رشته): رشته
کلید پذیرش دست دادن را از کلید کارخواه می‌سازد (RFC 6455).
net-websocket-Handshake.salam
واردسازی شبکه.وب‌سوکت
واردسازی رشته

تابع ریشه:
    سرچاپ وب‌سوکت.کلید پذیرش("dGhlIHNhbXBsZSBub25jZQ==")
    د := وب‌سوکت.درخواست دست دادن("example.com"، "/chat"، "dGhlIHNhbXBsZSBub25jZQ==")
    سرچاپ رشته.تفکیک کردن(د، "\r\n")[۰]
    د۲ := وب‌سوکت.درخواست دست دادن با سربرگ("example.com"، "/chat"، "dGhlIHNhbXBsZSBub25jZQ=="، "Authorization: Bearer x\r\n")
    سرچاپ رشته.شامل است(د۲، "Authorization: Bearer x")
    پ := وب‌سوکت.پاسخ دست دادن(د)
    سرچاپ رشته.تفکیک کردن(پ، "\r\n")[۰]
    سرچاپ رشته.شامل است(پ، "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=")
پایان
خروجیs3pPLMBiTxaQ9kYGzzhZRbK+xOo= GET /chat HTTP/1.1 true HTTP/1.1 101 Switching Protocols true

پاسخ دست دادن HandshakeResponse

تابع پاسخ دست دادن(request: رشته): رشته
پاسخ ۱۰۱ سرور به یک درخواست دست دادن.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Handshake.salam

درخواست دست دادن HandshakeRequest

تابع درخواست دست دادن(host: رشته، path: رشته، key: رشته): رشته
متن درخواست دست دادن کارخواه.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Handshake.salam

درخواست دست دادن با سربرگ HandshakeRequestWith

تابع درخواست دست دادن با سربرگ(host: رشته، path: رشته، key: رشته، extra: رشته): رشته
درخواست دست دادن با سرآیندهای اضافه.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Handshake.salam

شنود Listen

تابع شنود(port: صحیح): سرور
سرور وب‌سوکت روی درگاه داده‌شده؛ صفر یعنی درگاه آزاد و آن‌گاه درگاه می‌گوید کدام است (فیلد port صفر می‌ماند).

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

معتبر Ok

تابع معتبر(srv: سرور): منطقی
سرور درست ساخته شد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

درگاه Port

تابع درگاه(srv: سرور): صحیح
درگاه سرور.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

بستن سرور CloseServer

تابع بستن سرور(srv: سرور)
سرور را می‌بندد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

پذیرش Accept

تابع پذیرش(srv: سرور): اتصال وب
منتظر کارخواه بعدی می‌ماند و دست دادن وب‌سوکت را کامل می‌کند. اگر درخواست ارتقای درست وب‌سوکت نباشد اتصال بسته برمی‌گردد، پس باز است را بسنجید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

بارگذاری پیکربندی امن LoadWSSConfig

تابع بارگذاری پیکربندی امن(cert_file: رشته، key_file: رشته)
گواهی و کلید TLS را که پذیرش امن به کار می‌برد بارگذاری می‌کند. این یک تنظیم برای کل برنامه است.
net-websocket-WSS.salam
واردسازی شبکه.وب‌سوکت

تابع ریشه:
    ناپایا ک := وب‌سوکت.شماره گیری امن("echo.example.com"، ۴۴۳، "/")
    ناپایا ک۲ := وب‌سوکت.شماره گیری امن با سربرگ("echo.example.com"، ۴۴۳، "/"، "Origin: https://salamlang.ir\r\n")
    ناپایا ک۳ := وب‌سوکت.شماره گیری امن بدون بررسی("localhost"، ۸۴۴۳، "/"، "")
    سرچاپ وب‌سوکت.باز است(ک)، وب‌سوکت.باز است(ک۲)، وب‌سوکت.باز است(ک۳)
    وب‌سوکت.بارگذاری پیکربندی امن("cert.pem"، "key.pem")
    س := وب‌سوکت.شنود(۸۴۴۳)
    ناپایا ا := وب‌سوکت.پذیرش امن(س)
    _ := وب‌سوکت.ارسال متن(ا، "سلام")
    وب‌سوکت.بستن(ا)
پایان

پذیرش امن AcceptWSS

تابع پذیرش امن(srv: سرور): اتصال وب
اتصال امن (wss) می‌پذیرد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-WSS.salam

شماره گیری Dial

تابع شماره گیری(host: رشته، port: صحیح، path: رشته): اتصال وب
به سرور وب‌سوکت وصل می‌شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

شماره گیری با سربرگ DialWith

تابع شماره گیری با سربرگ(host: رشته، port: صحیح، path: رشته، extra: رشته): اتصال وب
مثل تابع بالا، با سرآیندهای اضافه؛ هر سرآیند با \r\n تمام شود.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Hub.salam

شماره گیری امن DialWSS

تابع شماره گیری امن(host: رشته، port: صحیح، path: رشته): اتصال وب
اتصال امن (wss).

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-WSS.salam

شماره گیری امن با سربرگ DialWSSWith

تابع شماره گیری امن با سربرگ(host: رشته، port: صحیح، path: رشته، extra: رشته): اتصال وب
اتصال امن با سرآیندهای اضافه.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-WSS.salam

شماره گیری امن بدون بررسی DialWSSUnverified

تابع شماره گیری امن بدون بررسی(host: رشته، port: صحیح، path: رشته، extra: رشته): اتصال وب
اتصال امن بدون بررسی گواهی؛ فقط برای آزمایش با گواهی خودامضا.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-WSS.salam

باز است IsOpen

تابع باز است(c &: اتصال وب): منطقی
اتصال باز است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

دریافت پیام Receive

تابع دریافت پیام(c &: اتصال وب): پیام
پیام کامل بعدی را می‌گیرد و هر قدر لازم باشد صبر می‌کند. به پینگ خودکار پاسخ می‌دهد و پیام‌های تکه‌تکه را سر هم می‌کند؛ با رسیدن قاب بستن پاسخ می‌دهد و اتصال را می‌بندد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

دریافت با مهلت Poll

تابع دریافت با مهلت(c &: اتصال وب، timeout_ms: صحیح): پیام
مثل تابع بالا، با حداکثر چند میلی‌ثانیه صبر؛ اگر چیزی نرسد نوع پیام مهلت است. زمان منفی یعنی صبر بی‌پایان.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

دریافت متن ReceiveText

تابع دریافت متن(c &: اتصال وب): رشته
متن پیام بعدی، یا رشته‌ی خالی اگر پیام بعدی متنی نباشد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

متن است IsText

تابع متن است(m: پیام): منطقی
پیام متنی است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

دودویی است IsBinary

تابع دودویی است(m: پیام): منطقی
پیام دودویی است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

بسته است IsClose

تابع بسته است(m: پیام): منطقی
پیام بستن است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

پونگ است IsPong

تابع پونگ است(m: پیام): منطقی
پیام پاسخ پینگ است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

ارسال متن SendText

تابع ارسال متن(c &: اتصال وب، msg: رشته): صحیح
پیام متنی می‌فرستد؛ ۰ برمی‌گرداند، یا عددی منفی اگر اتصال از دست رفته باشد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

ارسال دودویی SendBinary

تابع ارسال دودویی(c &: اتصال وب، data: رشته): صحیح
پیام دودویی از بایت‌های رشته می‌فرستد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

ارسال بایت دودویی SendBinaryBytes

تابع ارسال بایت دودویی(c &: اتصال وب، ptr: تهی*، n: صحیح): صحیح
پیام دودویی از حافظه می‌فرستد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

پینگ فرست Ping

تابع پینگ فرست(c &: اتصال وب، data: رشته): صحیح
پینگ می‌فرستد؛ طرف دیگر باید پونگ برگرداند.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

بستن Close

تابع بستن(c &: اتصال وب)
قاب بستن را می‌فرستد و اتصال را می‌بندد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Echo.salam

توقف Stop

تابع توقف(c &: اتصال وب)
اگر اتصال باز باشد قاب بستن می‌فرستد و سوکت را بدون آزاد کردن اتصال می‌خواباند تا نخ دیگری که روی آن در دریافت پیام مانده بیدار شود. پس از آن برای آزادسازی بستن را صدا بزنید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Hub.salam

هاب جدید NewHub

تابع هاب جدید(): هاب
هاب خالی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Hub.salam

ثبت Register

تابع ثبت(h &: هاب، room: رشته، c: اتصال وب)
نسخه‌ای از اتصال را به اتاق اضافه می‌کند. برای چند نخ امن نیست.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Hub.salam

لغو ثبت Unregister

تابع لغو ثبت(h &: هاب، room: رشته، c: اتصال وب)
اتصال را با مقایسه‌ی سوکتش از اتاق برمی‌دارد؛ همان نسخه‌ای را بدهید که ثبت کرده‌اید، چون اتصال بسته‌شده شماره‌ی سوکتش را از دست داده است.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Hub.salam

اندازه اتاق RoomSize

تابع اندازه اتاق(h: هاب، room: رشته): صحیح
تعداد اعضای اتاق.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Hub.salam

پخش Broadcast

تابع پخش(h &: هاب، room: رشته، msg: رشته): صحیح
پیام متنی را به همه‌ی اعضای باز اتاق می‌فرستد و تعداد رسیده‌ها را برمی‌گرداند؛ برای اتاق ناشناخته ۰.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Hub.salam

پخش دودویی BroadcastBinary

تابع پخش دودویی(h &: هاب، room: رشته، data: رشته): صحیح
پیام دودویی را به همه می‌فرستد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: net-websocket-Hub.salam