PDA

View Full Version : سوال: چت به روش Comet



sattaryekta
سه شنبه 26 بهمن 1389, 14:28 عصر
آیا درست متوجه شدم؟
اگر از یک اسکریت php به عنوان سرور استفاده کنیم باید یکجایی اجرا متوقف بشه.
مثلا کد زیر:
اطلاعات افراد داخل چت روم در یک فایلی که اینجا filename هست ذخیره میشوند.

$lastmodif = isset($_GET['timestamp']) ? $_GET['timestamp'] : 0;
$currentmodif = filemtime($filename);
while ($currentmodif <= $lastmodif) // check if the data file has been modified
{
usleep(10000); // sleep 10ms to unload the CPU
clearstatcache();
$currentmodif = filemtime($filename);
}فکر میکنم این حلقه تا زمانی که از یک کاربر دیگه یک پیغام جدید برای چت ارسال نشه اسکریپت را در حال اجرا نگه میداره.
اگر اینطور باشه، max_execution_time جلوی اجرای اسکریپت را نخواهد گرفت؟

amir001
سه شنبه 26 بهمن 1389, 17:33 عصر
اگر کل برنامه را درون (while(1 قرار بدی تا زمانی که سوکتت قطع بشه برنامه ات خاتمه پیدا نمیکنه.
PHP امکان استفاده از نخها را نداره و نمیتونی در یک اجرا همزمان به درخواست چندین نفر پاسخ بدی. مگر اینکه برای هر نفر یک درخواست ارسال کنی که اون هم دیگه نمیشه Comet (منظورم برای استفاده در چت بود.)

برای بینهایت کردن زمان اجرای برنامه ات از تابع زیر استفاده کن
set_time_limit(0)

از اسکریپتی که در سایت زیر قرار داده شده فکر کنم بتونی برای چت هم استفاده کنی.
خودش توی توضیحاتش گفته Comet

http://www.ape-project.org/

eshpilen
سه شنبه 26 بهمن 1389, 19:34 عصر
من یبار خواستم Comet رو تست کنم. ولی هرچی در PHP اکو میکردم به مرورگر ارسال نمیشد تا زمانی که اجرای اسکریپت PHP کاملا تموم میشد. فکر کنم بخاطر اینکه آپاچی خروجی رو بافر میکرد. یعنی هر چیزی که اکو میکنید فورا ارسال نمیشه. هرچی هم سعی کردم Flush کنم فایده نداشت.
ضمنا در Comet حتما باید مکانیزمی باشه (احتمالا سمت کلاینت) که درصورتیکه اتصال قطع شد دوباره اتصال رو برقرار بکنه (با یه درخواست دیگه). حتی اگر از set_time_limit(0) استفاده کنید این تضمینی نمیده که حین کار اتصال بسته نشه و اجرای اسکریپت PHP هم توسط سرور بطور خودکار خاتمه پیدا نکنه.
بنابراین فکر میکنم پیاده سازی درست و حسابی یه مقدار پیچیده هست.
بخاطر همین بهتره از یک اسکریپت و کتابخانهء آماده ای چیزی استفاده کنید.
راستی Reverse Ajax (http://en.wikipedia.org/wiki/Reverse_Ajax) هم فکر میکنم درواقع همون روش Comet هست.

sattaryekta
چهارشنبه 27 بهمن 1389, 07:58 صبح
هرچی در PHP اکو میکردم به مرورگر ارسال نمیشد تا زمانی که اجرای اسکریپت PHP کاملا تموم میشد
من هم یک اسکریپت از اینجا گرفتم ولی دچار همین مشکل شدم!
http://www.zeitoun.net/articles/comet_and_php/start
تابع set_time_limit میتونه باعث بشه که اسکریپت به صورت 24 ساعته در حالت اجرا باقی بمونه؟ مثلا روی سروری که کانفیگش دست ما نیست.

eshpilen
چهارشنبه 27 بهمن 1389, 11:12 صبح
تابع set_time_limit میتونه باعث بشه که اسکریپت به صورت 24 ساعته در حالت اجرا باقی بمونه؟ مثلا روی سروری که کانفیگش دست ما نیست.

اصلا همچين فرضي نكنيد.
بايد روشي پياده شده باشه كه قطع شدن ارتباط رو تشخيص بده و دوباره ارتباط رو برقرار كنه.
حالا نميدونم چطوري. مثلا شايد در فواصل زماني معيني يك كد خاص رو ارسال/چك كنيم و غيره.

sattaryekta
چهارشنبه 27 بهمن 1389, 12:04 عصر
بايد روشي پياده شده باشه كه قطع شدن ارتباط رو تشخيص بده و دوباره ارتباط رو برقرار كنه
فکر میکنم در این روش پیگیری ارتباط قطع شده بر عهده Client هست:


onComplete: function(transport) {
// send a new ajax request when this request is finished
if (!this.comet.noerror)
// if a connection problem occurs, try to reconnect each 5 seconds
setTimeout(function(){ comet.connect() }, 5000);
else
this.comet.connect();
this.comet.noerror = false;
}

این یک قسمت ار کدی هست که وظیفه ارتباط مجدد در صرت قطع شدن ارتباط را بر عهده داره.
من کد زیر را روی سرور آپلود کردم. set_time_limit درست کار میکنه.


set_time_limit(0);
echo date('h:i:s') . "\n";
usleep(40000000);
echo date('h:i:s') . "\n";

در این آدرس:
http://www.ordup.com/t.php
اسکریپت بسیار ساده ایست ولی من فکرشو نمیکردم که امنیت سرور اجازه اجرا بیش از 30 ثانیه حتی با وجود set_time_limitرا بده!

eshpilen
چهارشنبه 27 بهمن 1389, 17:28 عصر
بنظرم حتما قسمتی برای چک کردن برقراری ارتباط و اتصال مجدد باید در برنامه باشه. چون حتی اگر set_time_limit هم بدون محدودیت کار کنه، همیشه احتمال قطع شدن ارتباط بنا به دلایل مختلف دیگری وجود داره.

راستی اگر موفق شدید به ما هم خبر بدید و نکته های مهمی رو که باید اجرا کنیم ذکر کنید.