فرستادن پیام
در علوم کامپیوتر، فرستادن پیغام تکنیکی است که برای فراخوانی یک رفتار (مثلاً اجرای یک برنامه) روی یک کامپیوتر انجام می‌شود. برنامه فراخواننده، یک پیغام را به یک پروسه می‌فرستد (که ممکن است یک عملگر یا شیء باشد) و سپس، روی آن پروسه و زیر ساخت‌های حمایت کنندهٔ آن تکیه می‌کند تا برخی کدهای مناسب را انتخاب و اجرا کند. انتقال پیغام با برنامه‌نویسی مرسوم فرق دارد. در برنامه‌نویسی مرسوم، یک پروسه، ساب روتین، یا تابع به‌طور مستقیم با استفاده از یک نام، فراخوانی می‌شود. انتقال پیغام یک اصل مهم برای برخی مدل‌های همروندی و برنامه‌نویسی شیء گرا است. انتقال پیغام، به‌طور گسترده‌ای در نرم‌افزارهای کامپیوترهای کنونی استفاده می‌شود. انتقال پیغام در اشیائی که یک برنامه را تشکیل می‌دهند، به عنوان شیوه ای برای کار کردن با یکدیگر، و برای اشیاء و سیستم‌هایی که روی کامپیوترهای مختلف اجرا می‌شوند (مثلاً اینترنت)، به عنوان روشی برای تعامل استفاده می‌شود. انتقال پیغام را می‌توان با استفاده از مکانیسم‌های مختلفی پیاده‌سازی کرد، از جمله کانال‌ها.
فرستادن پیغام یک تکنیک برای فراخوانی رفتار (مثلاً اجرای یک برنامه) روی یک کامپیوتر است. در روش فرستادن پیغام، برخلاف تکنیک مرسوم فراخوانی یک برنامه با استفاده از نام، از یک مدل اشیائی برای افتراق تابع کلی از پیاده‌سازی‌های خاص استفاده می‌شود. برنامهٔ فراخواننده یک پیغام می‌فرستد و روی شیء مورد نظر تکیه می‌کند تا کد مناسب را انتخاب و اجرا کند. توجیه استفاده از یک لایه بینابینی اساساً در دو مقوله قرار می‌گیرد: بسته‌بندی (به انگلیسی: encapsulation) و توزیع. انکپسولیشن ایده ای است که در آن اشیاء نرم‌افزار باید قادر باشند خدماتی را روی سایر اشیا فراخوانی کنند، بدون اینکه بدانند یا توجه کنند که چگونه این سرویس‌ها پیاده‌سازی می‌شود. انکپسولیشن می‌تواند مقدار منطق کد گذاری را کم کند و قابلیت تعمیر سیستم‌ها را افزایش دهد؛ مثلاً یک توسعه دهنده به جای استفاده از عبارت if-then، برای تعیین اینکه کدام ساب روتین یا تابع را فراخوانی کند، می‌تواند فقط یک پیغام به شیء مورد نظر بفرستد و شیء مورد نظر بر اساس نوع خودش، کد مناسب را انتخاب خواهد کرد. یکی از اولین مثال‌هایی که نشان داد، چگونه می‌توان از این روش استفاده کرد، مربوط به حوزهٔ گرافیک کامپیوتری بود. پیچیدگی‌های مختلفی در رابطه با دستکاری اشیاء گرافیکی وجود دارد. برای مثال، صرف استفاده از فرمول مناسب برای محاسبهٔ مساحت یک شیء محصور، می‌تواند بسته به اینکه شکل مثلث، مربع، بیضی یا دایره باشد، تغییر کند. در برنامه‌نویسی کامپیوتری قدیمی، این وضعیت منجر به عبارات طولانی IF-THEN می‌شد، این عبارات تست می‌کردند که شکل مورد نظر از چه نوع شیء ای است و کد مناسب را فراخوانی می‌کردند. روش شیء گرایانه برای حل این مشکل این است که، یک کلاس به نام codice_1 همراه با زیر کلاس‌هایی نظیر codice_2 و codice_3 (که خود دارای زیر کلاس‌های codice_2 و codice_5 هستند) تعریف کنیم و سپس به راحتی یک پیغام را به هر شکلی بفرستیم و درخواست کنیم تا مساحت خود را محاسبه کند. سپس هر شیء مربوط به شکل، متد زیر-کلاس را، همراه با فرمول مناسب برای آن نوع از شیء فراخوانی خواهد کرد.
انتقال پیغام توزیع شده، برای توسعه دهندگان لایه ای از معماری فراهم می‌کند که بتوانند سرویس‌های مشترکی را برای ساختن سیستم‌هایی متشکل از زیر سیستم‌ها، که روی کامپیوترهای مختلف، در مکان‌های مختلف و در زمان‌های مختلف اجرا می‌شوند، به کار گیرند. زمانی که یک شیء توزیع‌شده یک پیغام را می‌فرستد، لایهٔ پیغام رسانی می‌تواند مشکلاتی از این دست را مرتفع کند:
انتقال پیغام همگام بین اشیائی رخ می‌دهد که به صورت همزمان اجرا می‌شوند. این روش توسط زبان‌های برنامه‌نویسی شیء گرا، نظیر جاوا و Smalltalk استفاده می‌شود. پیغام رسانی همگام، شبیه فراخوانی همگام تابع است. همچنانکه فراخوانندهٔ تابع صبر می‌کند تا تابع کامل شود، پروسهٔ فرستنده صبر می‌کند تا پروسهٔ گیرنده کامل شود. این وضعیت می‌تواند در برخی موارد ارتباط همگام را نامیسر کند. برای مثال، سیستم‌های توزیع شدهٔ بزرگ ممکن است به اندازه‌ای خوب عمل نکنند تا قابل استفاده باشند. این سیستم‌های توزیع شده بزرگ، ممکن است نیاز باشد تا زمانی که برخی از زیر سیستم‌های آنها برای تعمیرات متوقف شده‌اند، بتوانند کار کنند. یک سازمان تجاری شلوغ را در نظر بگیرید که دارای صد کامپیوتر رومیزی است که فقط با استفاده از فرستادن پیغام همگام به یکدیگر ایمیل می‌فرستند. در این حالت اگر یک کارمند، کامپیوتر خود را خاموش کند می‌تواند باعث شود تا ۹۹ کامپیوتر دیگر، تا زمانیکه کارمند مورد نظر مجدداً کامپیوتر خود را روشن کند تا یک ایمیل را پردازش کند، متوقف شوند.
در رابطه با انتقال پیغام ناهمگام، شیء گیرنده در زمانیکه شیء درخواست کننده پیغام مورد نظر را می‌فرستد، می‌تواند خاموش یا مشغول باشد. در مقایسهٔ مجدد با فراخوانی تابع، این حالت شبیه یک فراخوانی تابع است که بلافاصله برمی گردد و منتظر نمی‌ماند تا تابع مورد فراخوانی کامل شود. پیغام‌ها به یک صف فرستاده می‌شوند و در آنجا ذخیره می‌شوند تا زمانیکه پروسهٔ دریافت کننده، آن‌ها را درخواست کند. پروسهٔ دریافت کننده، پیغام‌های خود را پردازش می‌کند و نتایج را به صف می‌فرستد. نتایج موجود در این صف توسط پروسهٔ اولیه یا برخی پروسه‌های بعدی مشخص شده برداشته می‌شوند.
پیغام رسانی ناهمگام، نیازمند قابلیت‌های اضافه برای ذخیره کردن و ارسال مجدد داده برای سیستم‌هایی است که ممکن است به‌طور همزمان اجرا نشوند و به‌طور کلی، توسط یک لایهٔ بینابینی نرم‌افزاری (که معمولاً میان افزار نام دارد) اجرا می‌شود. یک نوع معمول آن، میان افزار مبتنی بر پیغام (به انگلیسی: Message-oriented middleware) است.
بافری که برای ارتباط ناهمگام لازم است، در صورتی که پر شود، می‌تواند مشکل ساز شود. باید تصمیم‌گیری شود که آیا فرستنده مسدود شود یا اینکه پیغام‌های بعدی دور انداخته شوند. مسدود کردن فرستنده ممکن است منجر به بن‌بست شود. اگر پیغام‌ها دور انداخته شوند در این صورت ارتباط دیگر قابل اعتماد نیست.
می‌توان با استفاده از یک همگام ساز، ارتباط همگام را روی ارتباط ناهمگام سوار کرد. برای مثال همگام ساز آلفا، به این شکل کار می‌کند که فرستنده باید همیشه منتظر یک پیغام تأیید از سوی گیرنده باشد. فرستنده فقط زمانی می‌تواند پیغام بعدی را بفرستد که برای پیغام قبلی خود تاییدیه دریافت کرده باشد. از سوی دیگر، ارتباط ناهمگام را نیز می‌توان روی ارتباط همگام سوار کرد. برای مثال، میکروکرنل‌های جدید، به‌طور کلی، فقط یک عنصر پیغام رسانی همگام را فراهم می‌کنند. پیغام رسانی ناهمگام را می‌توان با استفاده از ریسمان های کمک کننده روی آن سوار کرد.
سیستمهای فرستادن پیغام، یا از اشیاء توزیع شده یا از اشیای محلی استفاده می‌کنند. در رابطه با اشیاء توزیع شده، فرستنده و گیرنده ممکن است روی کامپیوترهای مختلفی باشند و در حال اجرای سیستم‌های عامل متفاوتی باشند و از زبان‌های برنامه‌نویسی مختلفی استفاده کنند و …. در این مورد، لایهٔ گذرگاه، مسئول جزئیات مربوط به تبدیل داده از یک سیستم به سیستم دیگر، فرستادن و دریافت داده‌های بین شبکه ای و … است. پروتکل رویه ای دور (RPC) در یونیکس، مثالی قدیمی از این دست است. توجه داشته باشید که در این نوع از فرستادن پیغام، الزامی وجود ندارد که گیرنده یا فرستنده از برنامه‌نویسی شیء گرا استفاده کنند.treated as large grained objects capable of sending and receiving messages.
مثال‌هایی از سیستم‌هایی که از اشیاء توزیع شده پشتیبانی می‌کنند عبارتند از: Emerald, ONC RPC, CORBA, Java RMI, DCOM, SOAP, .NET Remoting, CTOS, QNX Neutrino RTOS, OpenBinder و D-Bus. سیستم‌های اشیاء توزیع شده را، سیستم‌های بدون اشتراک نیز می‌نامند، زیرا فرم انتزاعی فرستادن پیام، باعث مخفی شدن تغییرات وضعیتی ای می‌شود که ممکن است در پیاده‌سازی فرستادن پیغام‌ها استفاده شود.
انتقال پیغام توزیع شده یا ناهمگام، در مقایسه با فراخوان یک رویه، دارای سربار بیشتری است. در فرستادن پیغام، آرگومان‌ها باید در پیغام جدید کپی شوند. برخی آرگومان‌ها می‌توانند حاوی داده‌هایی به اندازه مگابایت باشند که همهٔ آنها باید کپی شده و به شیء دریافت کننده منتقل شوند.
فراخوان‌های رویه ای مرسوم، از لحاظ استفاده از حافظه، زمان انتقال، و محلی بودن، با فرستادن پیغام تفاوت دارند. معمولاً آرگومان‌ها، به وسیلهٔ رجیسترهای دارای کاربرد عمومی به گیرنده داده می‌شوند، که در این حالت، نیاز به فضای ذخیره اضافی یا زمان انتقال نمی‌باشد. آرگومان‌ها همچنین معمولاً در یک لیست پارامتری که حاوی آدرسهای آرگومان‌ها (چندین بیت) است، به گیرنده داده می‌شوند. فرستادن آدرس برای سیستم‌های توزیع شده امکان‌پذیر نیست، زیرا این سیستم‌ها از فضاهای آدرس مجزا استفاده می‌کنند.
مرورگرهای وب و سرورهای وب، مثال‌هایی از پروسه‌هایی هستند که به شیوهٔ فرستادن پیغام با یکدیگر ارتباط برقرار می‌کنند. یک URL، مثالی از ارجاع به یک منبع، بدون آشکار کردن محتویات داخلی پروسه است. یک فراخوان ساب روتین، یا فراخوان متد، تا زمانیکه محاسبهٔ فراخوانی شده خاتمه نیافته‌است، خارج نخواهد شد.
این در حالیست که، فرستادن پیغام ناهمگام ممکن است منجر به پاسخی شود که پس از گذشت زمان چشمگیری از فرستاده شدن پیغام درخواست، می‌رسد.
به‌طور کلی، یک مدیریت کنندهٔ پیغام، پیغام‌هایی را از بیش از یک فرستنده پردازش خواهد کرد. این بدان معنی است که، وضعیت آن می‌تواند به دلایلی نامرتبط با رفتار یک فرستنده یا پروسهٔ مشتری (کلاینت) تغییر کند، که تفاوت بسیاری با رفتار معمول شیء ای دارد که متدها بر روی این فراخوانی می‌شوند. این انتظار را داریم که مورد دوم، بین فراخوانی‌های متد، در وضعیت مشابهی باقی بماند. به عبارت دیگر، مدیریت کننده پیغام، رفتاری مشابه با یک شیء تغییرپذیر(volatile) دارد.