View Full Version : سوال در مورد وبسرویس و سوکت پروگرمینگ
a_mogheimi
پنج شنبه 26 شهریور 1394, 11:50 صبح
سلام.
وب سرویسی میخواهیم راه اندازی کنیم که این وبسرویس باید ارتباط دائمی با یک سرور دیگر از طریق سوکت داشته باشه. درخواستهایی که کاربر به وبسرویس ارسال میکنه بعد از پردازش به سرور مربوطه ارسال و پاسخ دریافتی به عنوان خروجی وبسرویس به کاربر ارسال میشه. یعنی در اصل ما میخواهیم یک رابط بین سرور و کاربر ایجاد کنیم .
ما با اتصال به سرور توسط سوکت مشکلی نداریم و اتصال انجام میشه . راه اندازی وبسرویس رو هم از طریق قرار دادن IdHTTPServer بر روی فرم و اعمال تنظیمات فراهم کردیم . ارسال و دریافت و پاسخ کاربر به درستی انجام میشه. تنها مشکلمون به زبان ساده اینه که :
هر کاربری که درخواست به وبسرویس ارسال میکنه ممکنه چندین درخواست رو برای سرور بفرسته که این وبسرویس باید تمامی درخواست ها رو به ترتیب و پشت سر هم به سرور ارسال کنه و در نهاست پاسخ رو به کاربر نمایش بده . در زمانی که یک کاربر این کارو انجام بده تست شده و مشکلی بوجود نمیاد ولی در صورتی که تعداد کاربران همزمان بیشتر بشه چه راهکاری رو پیشنهاد میکنید که تداخلی در ارسال ها و دریافت ها به سرور برای کاربرا پیش نیاد .
آیا کامپوننت IdHTTPServer این امکان رو فراهم میکنه که درخواست ها رو به ترتیب انجام بده ؟ چون در صورتی که در بین درخواست های ارسالی یک کاربر ، کاربر دیگری درخواستی رو به سرور ارسال کنه کلیه عملیات کاربر قبلی با اختلال مواجه میشه .
آیا این روش برای این مورد قابل استفاده است ؟
لطفا راهکارها و پیشنهادات خودتون رو بفرمائید .
(در مورد انتخاب عنوان نامناسب شرمنده ام)
با تشکر
Mask
پنج شنبه 26 شهریور 1394, 22:10 عصر
سلام
برای این کار باید از ارتباط موازی یا مالتی تردینگ بهره ببرید.
در این روش هر درخواست در ترد جدا پردازش میشود.
a_mogheimi
شنبه 04 مهر 1394, 07:59 صبح
ما توانایی ارسال درخواست به صورت موازی رو نداریم و باید درخواست ها به ترتیب ارسال بشه یعنی کلیه درخواستهای یک کاربر ارسال بشه و بعد از اتمام ارسال تمامی درخواست های اون کاربر درخواستهای کاربر بعدی به ترتیب ارسال بشه. در مورد مالتی تردینگ اطلاعی ندارم میشه نحوه استفاده از مالتی ترد رو در IdHTTPServer توضیح بدید ؟
Mask
دوشنبه 06 مهر 1394, 14:59 عصر
ما توانایی ارسال درخواست به صورت موازی رو نداریم و باید درخواست ها به ترتیب ارسال بشه یعنی کلیه درخواستهای یک کاربر ارسال بشه و بعد از اتمام ارسال تمامی درخواست های اون کاربر درخواستهای کاربر بعدی به ترتیب ارسال بشه. در مورد مالتی تردینگ اطلاعی ندارم میشه نحوه استفاده از مالتی ترد رو در IdHTTPServer توضیح بدید ؟
بهترین و کم دردسرترین راهی رو که بهتون پیشنهاد میکنم، استفاده از سورس وب سرور مجموعه OverByte هست.
a_mogheimi
سه شنبه 07 مهر 1394, 11:15 صبح
لطفا راهکار ارائه بدید
یوسف زالی
سه شنبه 07 مهر 1394, 13:17 عصر
سلام.
پیاده سازی شما چه شکلیه؟
اگر من درخواستی بدم و همکارم درخواستی بده، باید درخواستش wait بمونه؟
این طوری که ددلاک پیش میاد.
توضیحاتتون برای ارائه راهکار کافی نیست.
Mahmood_M
سه شنبه 07 مهر 1394, 15:11 عصر
آیا از بانک اطلاعاتی استفاده می کنید ؟
وب سرویس بعد از دریافت درخواست چه کاری انجام میده ؟
باید یک لایه میانی ایجاد کنید که درخواست های کاربر رو هم با سوکت مدیریت کنید
یک کلاس به عنوان "درخواست " ایجاد کنید و یک شناسه ( مثل IP کلاینت ) و اطلاعات درخواست مربوط به کلاینت رو درونش قرار بدید ، با هر بار ارسال درخواست به سرور یک کلاس از نوع " درخواست " درون سرور ساخته میشه و در یک لیست قرار می گیره ، ترتیب اجرای درخواستها هم میشه مثلا Index درخواست ها درون لیست
برای اجرای هر درخواست در سرور ، یک Thread ساخته میشه ، درون Thread عملیات مورد نظر رو انجام میدید ، در پایان کار Thread نتیجه رو با یک Message به اطلاع برنامه می فرستید ( منظور از Message مثلا ارسال نتیجه با PostMessage به Thread اصلی هستش ) ، برنامه با دریافت Message متوجه میشه که کار Thread و درخواست مورد نظر تمام شده و نتیجه ی دریافتی رو به کلاینت مورد نظر که با IP شناخته شده ارسال می کنه و پس از ارسال ، Thread جدیدی ایجاد میشه و درخواست بعدی رو اجرا می کنه تا زمانی که لیست خالی بشه
درواقع وب سرویس شما فقط درخواست رو در لیست ثبت می کنه و جواب رو نمی فرسته ، فقط دریافت می کنه
دلیل استفاده از Thread هم اینه که با اجرای هر درخواست سرور شما به اصطلاح هنگ نکنه و همیشه آماده باشه
همینطور می تونید به جای لیستی از کلاینتها اطلاعات درخواست و کلاینت رو در بانک موقتی ذخیره کنید
در اینصورت Delay ایجاد شده فقط در زمان دریافت درخواست و ثبت در لیست ( یا بانک ) هست و بعید به نظر میرسه باعث تداخل بشه
موفق باشید ...
a_mogheimi
سه شنبه 07 مهر 1394, 18:24 عصر
سلام.
پیاده سازی شما چه شکلیه؟
اگر من درخواستی بدم و همکارم درخواستی بده، باید درخواستش wait بمونه؟
این طوری که ددلاک پیش میاد.
توضیحاتتون برای ارائه راهکار کافی نیست.
زمانی که یک درخواست به وبسرویس ارسال میشه باید تا اتمام پردازش اون درخواست (که شامل اتصال از طریق سوکت به سرور دیگر و دریافت اطلاعات ازآن سرور است) وبسرویس در حالت wait بمونه و درخواست جدیدی رو پردازش نکنه چون سروری که با سوکت بهش اتصال پیدا میکنیم در یک زمان فقط یک دستور رو انجام میده. و نمیتونیم همزمان چندین درخواست داشته باشیم.
شما فرض کنید سیستم رزروی هست که تا زمانی که اطلاعات درخواست یک به سرور ارسال نشه و رزرو انجام نشه اطلاعات بعدی نباید دریافت بشه و یا اگر دریافت میشه به سرور سوکتمون ارسال نشه و تو صف بمونه . اگه توضیحات کامل نیست بفرمائید بیشتر توضیح بدم
a_mogheimi
سه شنبه 07 مهر 1394, 19:12 عصر
آیا از بانک اطلاعاتی استفاده می کنید ؟
وب سرویس بعد از دریافت درخواست چه کاری انجام میده ؟
...
بذارید با یک مثال توضیح بدم :
درخواستمون رو به وبسرویس از طریق متد curl پی اچ پی ارسال میکنیم
روی فرممون از IdHTTPServer استفاده کردیم و از رویداد onCommandGet برای مدیریت دریافت ها و ارسال ها به شیوه زیر استفاده کردیم :
procedure TForm3.IdHTTPServer1CommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
var c:string;
begin
c:= ARequestInfo.Params[0];
if IdTCPClient2.Connected= true then
if writeln2(idtcpclient2,c)=true then
AResponseInfo.ContentText := readln2(idtcpclient2);
end;
writeln2 : تابعی که داده های دریافتی وبسرویس رو به سوکت ارسال میکنه
readln2 : تابعی که مقدار بازگشتی سوکت رو میخونه
متغییر C در اصل همون مقداری هست که توسط curl در پی اچ پی به وبسرویس ارسال کردیم بعد در این رویداد وبسرویس در صورتی که کانکشن سوکت برقرار باشه مقداری دریافتی c به سوکت ارسال میشه و پاسخ دریافتی به عنوان خروجی وبسرویس برگردانده میشه. این درصورتی که تک کاربره باشه مشکلی نداره حالا برای استفاده از چند کاربر همزمان در صورتی که بخواهیم درخواستهای ارسالی به وبسرویس رو در یک دیتابیس ذخیره کنیم و به عنوان مثال با تایمر هر یک ثانیه وضعیت رکورد های دیتابیس رو برای درخواست جدید چک کنیم و در صورتی که درخواستی موجود بود اون رو به سوکت ارسال کنیم و پاسخ رو دریافت کنیم و در دیتابیس ذخیره کنیم این پاسخ رو به چه صورتی در خروجی وبسرویس ارسال کنیم ؟
Mahmood_M
سه شنبه 07 مهر 1394, 21:11 عصر
جواب درخواست رو با سوکت ارسال کنید نه با وب سرویس
a_mogheimi
سه شنبه 07 مهر 1394, 22:36 عصر
جواب درخواست رو با سوکت ارسال کنید نه با وب سرویس
لطف میکنید بیشتر توضیح بدید که من چطور درخواستی رو که با curl به وبسرویس ارسال میکنم توسط سوکت دریافت کنم ؟
یوسف زالی
چهارشنبه 08 مهر 1394, 09:38 صبح
ببینید اگر سرویس دهنده دیتابیس شما مای اس کیو ال هست، یا اس کیو ال سرور، خب این دو خودشون مدیریت همزمانی رو انجام می دند.
پیشنهاد می کنم به این روش فکر کنید:
همه پردازش ها انجام شوند، و برای پردازش هایی که بیش از ظرفیت است، پیام عدم ثبت فرستاده بشه.
فرض کنید ده تا ظرفیت دارید، صد نفر می رن همزمان ثبت نام کنند؛ شما می تونید این تعداد رو هم از طریق اتصالات همزمان به سرور بانک داده، محدود کنید (روش پر دردسر و نامناسب)، هم می تونید در زمان ثبت با استفاده از قفل گذاری مناسب روی جداول اول تعداد رو ببینید بعد تصمیم بگیرید، در این زمان تمام درخواست ها wait می مونند. (روش بهتر)
نیازی به تایمر نیست، کافیه در کوئری های دیتابیس (یا اس پی ها) اون رو درست پیاده کنید.
با این روش مطمئن می شید که تعداد از حد مجاز هرگز بالاتر نخواهد رفت.
a_mogheimi
چهارشنبه 08 مهر 1394, 19:20 عصر
ببینید اگر سرویس دهنده دیتابیس شما مای اس کیو ال هست، یا اس کیو ال سرور، خب این دو خودشون مدیریت همزمانی رو انجام می دند.
پیشنهاد می کنم به این روش فکر کنید:
همه پردازش ها انجام شوند، و برای پردازش هایی که بیش از ظرفیت است، پیام عدم ثبت فرستاده بشه.
فرض کنید ده تا ظرفیت دارید، صد نفر می رن همزمان ثبت نام کنند؛ شما می تونید این تعداد رو هم از طریق اتصالات همزمان به سرور بانک داده، محدود کنید (روش پر دردسر و نامناسب)، هم می تونید در زمان ثبت با استفاده از قفل گذاری مناسب روی جداول اول تعداد رو ببینید بعد تصمیم بگیرید، در این زمان تمام درخواست ها wait می مونند. (روش بهتر)
نیازی به تایمر نیست، کافیه در کوئری های دیتابیس (یا اس پی ها) اون رو درست پیاده کنید.
با این روش مطمئن می شید که تعداد از حد مجاز هرگز بالاتر نخواهد رفت.
مشکل در مدیریت بانک اطلاعاتی نیست . مشکل رو خیلی ساده توضیح دادم زمانی که کاربری درخواستی رو میفرسته به وبسرویس ، وبسرویس ارتباطی با سرور دیگری از طریق سوکت برقرار میکنه و داده ای رو ارسال و پاسخی رو دریافت میکنه . تا اینجا هیچ مشکلی نیست . حالا اگر چند درخواست همزمان به وبسرویس ارسال بشه به چه صورتی این درخواست هارو مدیریت کنیم ؟
ما مشلمون با پیاده سازی این قسمت هست که به چه صورتی درخواستها رو مدیریت کنیم چون همزمان امکان اتصال به سوکت سرور دیگر رو نداریم و نمیتونیم چندین درخواست رو همزمان به سکوت ارسال و پاسخ رو دریافت کنیم و باید به ترتیب این کار انجام بشه و وقتی عملیات کاربر شماره یک تمام شد عملیات کاربر شماره 2 شروع بشه.
اگه فرض اینکه idhttpserver درخواست جدید رو تا زمانی که درخواست قبلی به پایان نرسه قبول نمیکنه درست باشه ما چطوری درخواست هامون رو با php به این وبسرویس ارسال کنیم و درخواست ها رو به چه صورتی در لیست قرار بدیم و بعد از پردازش درخواستها ، پاسخ های دریافتی از سوکت رو به چه صورتی به کاربر ارسال کنیم.
این فرایند رو میخواهیم پیاده سازی کنیم .
در حالت تک کاربره ، کاربر با curl مقداری رو به وبسرویس ارسال میکنه و درخواست با IdTCPClient به سوکت سرور دیگه ارسال میشه و پاسخ دریافتی از طریق رویداد onCommandGet کامپوننت idhttpserver به کاربر ارسال میشه.
با تشکر از صبر و پاسختون
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.