چالش ساخت پیام رسان

چرا؟

تقریبا یک ماهِ پیش بود که به صورت جدی تصمیم گرفتم از محدوده امن خودم خارج بشم. توی این مدت سعی کردم بیشتر بخونم و چیز های جدید رو امتحان کنم و توی حوزه کاریم فعال تر باشم.
همچنین یک سری چالش ها برای خودم مشخص کردم، یکی از اون سری چالش ها چالِشِ انجام پروژه های ساده و کوچیک هست. ساده هستن اما یک ویژگی دارن، اونم اینه که من نمیدونم چجوری باید انجامش بدم و این یعنی چالش.
من این پروژه رو برای خودم انجام دادم و کد های هر دو بخش سرور و کلاینت رو توی گیت‎هابم گذاشتم

اولین چالشِ من

اولین چالشی که انتخاب کردم ساخت یک برنامه پیام رسان ساده بود که این ویژگی ها رو داشته باشه:

  1. کاربر x بتونه به y پیامی متنی بفرسته و y بدون نیاز به رفرش کردن، پیام رو توی لیست گفت و گو ها ببینه
  2. برای این که نیاز به رفرش نباشه، هر ثانیه به سرور درخواست نزنه و از یک راهِ دیگه استفاده بشه
  3. ثبتنام و لاگین داشته باشه
  4. وقتی کاربر توی برنامه نیست و پیامی دریافت میکنه، نوتیفیکیشن بیاد براش
  5. کاربر بتونه ID خودش رو بده به دوستن و دوستش اون رو Add کنه، و فقط در این صورت بتونن به هم پیام بدن
  6. الگوی معماری برنامه MVP باشه (چون میخوام بیشتر یادش بگیرم بهش عادت کنم)
  7. سمت سرور رو با Lumen بنویسم (چون به این نتیجه رسیدم لاراول و اسلیم و … برای من خیلی بهترن تا PHP خام)
  8. از RXjava استفاده کنم (چون برنامه نویسی ری‎اکتیو کار نکردم تا حالا و دوست دارم یاد بگیرم)
  9. نسخه وب اون رو هم با React بنویسم (فرانت اند کار وب نیستم، فقط برای آشنایی با این غول تقریبا تازه وارد)
همچینم پروژه ساده و کوچیکی نشدا?

چجوری شروع کردم

اولین مرحله تحقیق کردن و پیدا کردن راه حله و منم این کارو انجام دادم

مهم ترین پارت این پروژه بخش سمت سرورشه. یه تحقیقی کردم و بعد از تحقیق کوتاهی که کردم متوجه شدم چند تا راه حل هست برای پیاده سازی سمت سرور پیام رسان ها به صورت real-time(شاید بیشتر باشه اما من فقط متوجه همینا شدم) :

  1. استفاده از تکنولوژی Socket که در صورتی که درست پیاده سازی بشه بهترین گزینست
  2. استفاده از سرویس های آماده مثل Contus Fly، Scaledrone، Pusher و … که در شرایطی خاص میتونه انتخاب عالی باشه
  3. استفاده از سرویس Firebase Cloud Message گوگل که به اختصار FCM هم بهش میگن

من راه سوم رو انتخاب کردم. سوکت اصولی تر بود اما پیاده سازیش سخت تر بود و چون نمیخواستم پروژه طولانی بشه ترجیح دادم فعلا نرم سراغش.

Firebase Cloud Message چی هست اصلا ؟

Firebase Cloud Messaging یک API قدرتمند است که به شما اجازه می دهد پیام ها را به صورت قابل اعتماد و مستقل از پلتفرمی که در حال توسعه است، ارسال کنید. با استفاده از FCM، توسعه دهندگان می توانند به کاربران اطلاع دهند که داده های جدید برای همگام سازی و ارسال پیام های اطلاع رسانی در دسترس هستند. این برای آزمایش، ارسال پیام های بازاریابی و تعامل بسیار مفید است. منبع

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

  1. کاربر دریافت کننده توی صفحه چت فرستنده پیام باشه
  2. کاربر دریافت کننده توی صفحه چت یک کاربر دیگه یا توی یک برنامه دیگه باشه یا هم اصلا با گوشی کار نکنه.

توی حالت اول باید دیتا و محتویات پیام رو بخونیم و به صفحه چت اضافه کنیم
توی حالت دوم هم باید محتویات رو به صورت یک نوتیفیکیشن، به کاربر دریافت کننده نشون بدیم و اعلام کنیم که پیام جدیدی دریافت کردی.
خیلی نمیخوام وارد جزئیات بشم که طولانی بشه، به نظرم کلیات کار رو بگم بهتره

سمت اندروید هم برای من دو تا چالش داشت، یکیش پیاده سازی MVP توی یک پروژه واقعی و اون یکی نشون دادن لیست conversation دو کاربر(که فقط نگران زمان بر بودن پیاده سازیش بودم).

چند تا مطلب و مقاله راجب MVP خوندم و چند تا سمپل دیدم و دستم اومد چی به چیه. واسه لیست گفت و گو هم یک سرچی زدم و یک کتابخونه خیلی عالی پیدا کردم که باعث شد زمان زیادی رو بتونم سیو کنم


پیاده سازی

بخش اندروید
زود با MVP کنار امدم و بهش عادت کردم، هرچند به نظرم سرعت کدنویسی رو یکم پایین تر میاره ولی در عوض کد ها تمیز تر و دیباگ راحت تر میشه. به‎جای RXjava از همون روش سنتی و broadcast استفاده کردم، اما به زودی به پروژه اضافش میکنم.
برنامه پنج تا اکتیویتی داره :

اسکرین شات اسکرین شات اسکرین شات اسکرین شات اسکرین شات

  • صفحه اول کاربر ثبتنام میکنه
  • صفحه دوم اگر قبلا ثبتنام کرده باشه لاگین میکنه
  • صفحه سوم لیست دوستاش رو میبینه(اگر تازه ثبتنام کرده باشه طبیعتا لیست خالیه)
  • صفحه چهارم کاربر میتونه پیام ها رو ببینه و پیام بفرسته
  • صفحه پنجم هم میتونه دوستاش رو حذف کنه یا با وارد کردن id دوستش رو اضافه کنه به لیست دوستاش.

کد های اندروید هم می‎تونید توی گیت‎هاب ببینید : mymessages-android

بخش سمت سرور
همونجور که گفتم قرار شد بک‎اند رو با لیومن بزنم.  لیومن در واقع همون لاراوله اما تمرکزش روی ساختن API هست و blade  و اینارو نداره.
اولین تجربه ساخت API با لیومن تجربه شیرینی بود، کد ها تر و تمیز و مفهوم، بدون هیچ چیز اضافه ای بودن.

دیتابیس هم mysql هست، به ساختار جدول ها یک نگاهی بندازید بد نیست. ساختار خیلی ساده داره :

  • جدول Users همونجور که از اسمش مشخصه اطلاعات کاربر ها توش ذخیره میشه.پسور ها هم با تابع Hash خود لاراول هش میشن
  • جدول Friends رابطه دوستی ها ی کاربر ها رو ذخیره میکنه. به عنوان مثال x با y دوسته و این دوستی یک id منحصر به فرد هم داره.
  • جدول Messages هم پیام های ارسالی رو دخیره میکننه. مهم ترین سطون این جدول friend_id هست که id دوستیِ دو کاربر با هم توش ذخیره میشه و ما با اون میتونیم راحت تر و با هزینه کمتری پیام های ارسالیِ بین دو کاربر رو بگیریم.

کد های این بخش رو می‎تونید توی گیت‎هاب ببینید : mymessages-lumen

بخش وب

هنوز نرفتم سمتش و توی روز های آینده حتما میرم سراغش و می‏‎سازمش


حرف پایانی؟

بک‎اند رو گذاشتم روی هاستم و برنامه رو وصل کردم بهش. چند روز تستش کردم و بدون مشکل کار میکنه.

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

Categories: برنامه نویسی

۲ دیدگاه

  • MkBahram

    سلام

    خیلی خوشحالم که میبینم یه پروژه جدید رو شروع کردی و این پروژه هم خیلی عالی هست از هر زمینه و تجربه خیلی خوبی به جا میذاره .

    اپ رو حتما دانلود میکنم و تست میکنم .

    موفق باشی :X:X:X:

    • فرزاد

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

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *