كيفية إنشاء تطبيق دردشة في عشرين دقيقة

صورة



يحب والدي أن يذكرني بأنه ، كمهندس كمبيوتر في السبعينيات ، " كان مبرمجًا قبل أن تصبح البرمجة عصرية ". حتى أنه عرض نصوص فورتران وكوبول القديمة عدة مرات. بعد قراءة هذا الرمز ، يمكنني القول بثقة أن البرمجة هي بالتأكيد أكثر برودة اليوم .



السمة المميزة للغات البرمجة الحديثة وبيئات التطوير هي مقدار القليل من التعليمات البرمجية التي يجب على المطور كتابتها. باستخدام لغات عالية المستوى جنبًا إلى جنب مع العديد من واجهات برمجة التطبيقات المتاحة وحزم مفتوحة المصدر والخدمات المدفوعة ، يمكن إنشاء التطبيقات - حتى تلك ذات المتطلبات المعقدة - بسرعة كبيرة.



المقارنة لإثبات تطور تطوير البرمجيات هي البناء. ذات مرة ، بدأ بناء أي منزل بقطع الأشجار على موقعك. ومع ذلك ، ظهرت المواد والأدوات والأساليب بسرعة بحيث تم الانتهاء من البناء بشكل أسرع ، وأصبحت الأشياء أقوى ، وتحرر العمال من بعض المهام الأولية.



كم عدد ناطحات السحاب التي سيتم بناؤها إذا قام البناة بتعدين الفولاذ الخاص بهم؟



مطورو البرمجيات ، الذين يواصلون العمل حتى يومنا هذا ، في فجر حياتهم المهنية "قطعوا أشجارهم بأنفسهم". في الوقت نفسه ، أدت الابتكارات غير المسبوقة في العقد الماضي إلى حقيقة أن صناعة البرمجيات بدأت في التطور بنفس طريقة البناء.



ببساطة ، يمتلك مطورو اليوم الأدوات والتقنيات وأفضل الممارسات لإكمال المشاريع بشكل أسرع والحصول على تطبيقات مستقرة وحفظ المطورين من المهام ذات المستوى المنخفض.



كيفية إنشاء تطبيق دردشة



دعنا نبتكر شيئًا سريعًا كان يستغرق أيامًا أو أسابيع. سنقوم بإنشاء تطبيق Public Chat Room يستخدم WebSockets للمراسلة في الوقت الفعلي.



يتم دعم WebSockets أصلاً بواسطة جميع المتصفحات الحديثة. ومع ذلك ، فإن هدفنا هو معرفة الأدوات التي يمكننا استخدامها في العمل ، وليس إعادة اختراعها . مع وضع ذلك في الاعتبار ، سوف نستخدم التقنيات التالية:



  • 8base  - واجهة برمجة تطبيقات GraphQL المُدارة
  • VueJS  - إطار عمل JavaScript


يمكن العثور على مشروع البداية وملف README الكامل في مستودع GitHub هذا . إذا كنت تريد فقط رؤية التطبيق المكتمل ، فقم بإلقاء نظرة على فرع غرفة الدردشة العامة.



بالإضافة إلى ذلك ، يشرح الفيديو أدناه (باللغة الإنجليزية) كل خطوة بمزيد من التفصيل.



لنبدأ.



سبع خطوات لإنشاء تطبيق دردشة:



1. إعداد المشروع



استنساخ مشروع البداية وانتقل إلى دليل الدردشة الجماعية. يمكنك أن تقرر بنفسك ما إذا كنت تريد استخدام الغزل أو npm لتثبيت تبعيات المشروع. على أي حال ، نحتاج إلى جميع حزم NPM المحددة في ملف package.json.



#  
git clone https://github.com/8base/Chat-application-using-GraphQL-Subscriptions-and-Vue.git group-chat
#   
cd group-chat
#  
yarn


للتفاعل مع واجهة برمجة تطبيقات GraphQL ، نحتاج إلى إعداد ثلاثة متغيرات للبيئة. قم بإنشاء ملف env.local في الدليل الجذر باستخدام الأمر التالي ، وسيقوم تطبيق Vue ، بعد التهيئة ، تلقائيًا بتعيين متغيرات البيئة التي أضفناها إلى هذا الملف. كلا القيمتين ولا ينبغي تغييرهما. ما عليك سوى تعيين القيمة . إذا كان لديك مساحة عمل 8base تريد استخدامها لإنشاء تطبيق دردشة باستخدام برنامجنا التعليمي ، فقم بتحديث ملف env.local بمعرف مساحة العمل الخاص بك. إذا لم يكن الأمر كذلك ، فاحصل على معرف مساحة العمل باتباع الخطوتين 1 و 2 من 8base Quickstart .



echo 'VUE_APP_8BASE_WORKSPACE_ID=<YOUR_8BASE_WORKSPACE_ID>

VUE_APP_8BASE_API_ENDPOINT=https://api.8base.com

VUE_APP_8BASE_WS_ENDPOINT=wss://ws.8base.com' \

> .env.local




VUE_APP_8BASE_API_ENDPOINTVUE_APP_8BASE_WS_ENDPOINTVUE_APP_8BASE_WORKSPACE_ID







2. مخطط الاستيراد



الآن نحن بحاجة إلى إعداد جانب الخادم. في جذر هذا المستودع ، يجب أن تجد الملف chat-schema.json. لاستيراده إلى مساحة العمل ، تحتاج فقط إلى تثبيت سطر أوامر 8base وتسجيل الدخول ، ثم استيراد ملف المخطط.



#  8base CLI
yarn global add 8base-cli
#  CLI
8base login
#      
8base import -f chat-schema.json -w <YOUR_8BASE_WORKSPACE_ID>


3. الوصول إلى API



تتمثل المهمة الأخيرة للواجهة الخلفية في السماح بالوصول العام إلى واجهة برمجة تطبيقات GraphQL.



في وحدة التحكم 8base ، انتقل إلى App Services > Roles > Guest. قم بتحديث الأذونات التي تم تعيينها لكل من المنشورات والمستخدمين ليتم فحصها أو تعيينها على أنها كل السجلات (كما هو موضح في لقطة الشاشة أدناه).



يحدد دور الضيف ما يُسمح للمستخدم الذي يقدم طلب واجهة برمجة تطبيقات غير مصدق القيام به.



صورة

محرر الدور في وحدة تحكم 8base.



4. كتابة استعلامات GraphQL



في هذه الخطوة ، سنقوم بتعريف وكتابة جميع استعلامات GraphQL التي سنحتاجها لمكون الدردشة الخاص بنا. سيساعدنا هذا في فهم البيانات التي سنقرأها وننشئها ونستمع إليها (عبر WebSockets) باستخدام واجهة برمجة التطبيقات.



يجب وضع الكود التالي في ملف src / utils / graphql.js. اقرأ التعليقات الموجودة فوق كل ثابت تم تصديره لفهم ما يفعله كل استعلام.




/* gql      graphQL */
import gql from "graphql-tag";
/* 1.    -   10  */
export const InitialChatData = gql`
{
  usersList {
    items {
      id
      email
    }
  }
  messagesList(last: 10) {
    items {
      content
      createdAt
      author {
        id
        email
      }
    }
  }
}
`;
/* 2.          */
export const CreateUser = gql`
mutation($email: String!) {
  userCreate(data: { email: $email, roles: { connect: { name: "Guest" } } }) {
    id
  }
}
`;
/* 3.   */
export const DeleteUser = gql`
mutation($id: ID!) {
  userDelete(data: { id: $id, force: true }) {
    success
  }
}
`;
/* 4.        */
export const UsersSubscription = gql`
subscription {
  Users(filter: { mutation_in: [create, delete] }) {
    mutation
    node {
      id
      email
    }
  }
}
`;
/* 5.          */
export const CreateMessage = gql`
mutation($id: ID!, $content: String!) {
  messageCreate(
    data: { content: $content, author: { connect: { id: $id } } }
  ) {
    id
  }
}
`;
/* 6.     . */
export const MessagesSubscription = gql`
subscription {
  Messages(filter: { mutation_in: create }) {
    node {
      content
      createdAt
      author {
        id
        email
      }
    }
  }
}
`;




5. تكوين عميل Apollo للاشتراكات



مع كتابة استعلامات GraphQL الخاصة بنا ، حان الوقت لإعداد وحدات API الخاصة بنا.



أولاً ، دعنا نتعامل ApolloClientمع عميل API بالإعدادات الافتراضية المطلوبة. بالنسبة createHttpLinkلنا ، نقدم نقطة نهاية مساحة العمل المكتملة لدينا. هذا الرمز بتنسيق src/utils/api.js.



import { ApolloClient } from "apollo-boost";
import { createHttpLink } from "apollo-link-http";
import { InMemoryCache } from "apollo-cache-inmemory";
const { VUE_APP_8BASE_API_ENDPOINT, VUE_APP_8BASE_WORKSPACE_ID } = process.env;

export default new ApolloClient({
link: createHttpLink({
  uri: `${VUE_APP_8BASE_API_ENDPOINT}/${VUE_APP_8BASE_WORKSPACE_ID}`,
}),
cache: new InMemoryCache(),
});

// Note:     ,    // ApolloClient,    .


ثم سنتعامل مع عميل الاشتراك باستخدام subscriptions-transport-wsو isomorphic-ws. هذا الرمز أطول قليلاً من الرمز السابق ، لذا من المفيد أخذ الوقت الكافي لقراءة التعليقات في الكود.



نقوم SubscriptionClientبالبدء باستخدام نقطة نهاية WebSockets الخاصة بنا وفي workspaceIdالمعلمات connectionParams. ثم نستخدم هذه subscriptionClientالطريقة في طريقتين محددتين في التصدير الافتراضي: subscribe()و close().



subscribeيسمح لنا بإنشاء اشتراكات جديدة مع عمليات استعادة البيانات والخطأ. طريقة الإغلاق هي ما يمكننا استخدامه لإغلاق الاتصال عندما نغادر الدردشة.



import WebSocket from "isomorphic-ws";
import { SubscriptionClient } from "subscriptions-transport-ws";
const { VUE_APP_8BASE_WS_ENDPOINT, VUE_APP_8BASE_WORKSPACE_ID } = process.env;

/**
*   ,  
*     .
*/

const subscriptionClient = new SubscriptionClient(
VUE_APP_8BASE_WS_ENDPOINT,
{
  reconnect: true,
  connectionParams: {
    /**
      * Workspace ID    ,  
*  Websocket  
*    
      */
    workspaceId: VUE_APP_8BASE_WORKSPACE_ID,
  },
},
/**
  *    WebSocket,   W3C. * ,        *WebSocket (,   NodeJS)
  */
WebSocket
);
export default {
/**
  *   ,      *'data’  'error’
  */
subscribe: (query, options) => {
  const { variables, data, error } = options;
  /**
    *     .
    */
  const result = subscriptionClient.request({
    query,
    variables,
  });
  /**
    *       * ,     , 
* subscriptionClient
    */
  const { unsubscribe } = result.subscribe({
    /**
      *       
* ,  .
      */
    next(result) {
      if (typeof data === "function") {
        data(result);
      }
    },
    /**
      *          ,  .
      */
    error(e) {
      if (typeof error === "function") {
        error(e);
      }
    },
  });
  return unsubscribe;
},
/**
  *  subscriptionClient .
  */
close: () => {
  subscriptionClient.close();
},
};
// .     SubscriptionClient   , 
// ,    .


6. كتابة مكون Vue



لدينا الآن كل ما نحتاجه لإنشاء محادثة عامة. لم يتبق سوى مكون واحد للكتابة GroupChat.vue.



قم بتحميل المكون باستخدام خدمة الغزل ودعنا نستمر.



ملاحظة مهمة: كل شخص لديه فكرته الخاصة عن الجمال ، لذلك قمت فقط بعمل الحد الأدنى من الأنماط الضرورية للمكون ليكون عمليًا.



البرنامج النصي المكون



أولاً ، نحتاج إلى استيراد وحداتنا وأنماطنا البسيطة واستعلامات GraphQL. كل هذا في بلدنا src / utils.

تعلن عن الواردات التالية في GroupChat.vue.



/* API  */
import Api from "./utils/api";
import Wss from "./utils/wss";

/* graphQL  */
import {
InitialChatData,
CreateUser,
DeleteUser,
UsersSubscription,
CreateMessage,
MessagesSubscription,
} from "./utils/graphql";
/*  */
import "../assets/styles.css";


بيانات المكون



يمكننا تحديد خصائص البيانات التي نريد استخدامها في وظيفة البيانات لمكوننا. كل ما نحتاجه هو وسيلة لتخزين مستخدمي الدردشة والرسائل واسم المستخدم "الحالي" وأي رسالة لم يتم إرسالها بعد. يمكن إضافة هذه الخصائص على النحو التالي:



/* imports ... */

export default {
name: "GroupChat",
data: () => ({
  messages: [],
  newMessage: "",
  me: { email: "" },
  users: [],
}),
};


خطافات دورة الحياة



تعمل خطافات دورة الحياة الخاصة بنا في نقاط مختلفة من عمر مكون Vue. على سبيل المثال عندما يتم تركيبه أو تحديثه. في هذه الحالة ، نحن مهتمون فقط بالإنشاء beforeDestroyوالمكون. في مثل هذه الحالات ، نريد إما فتح اشتراكات الدردشة أو إغلاقها.



/* ... */

export default {
/*   ... */

/**
  *   ,    .
  */
created() {
  /**
    *   ,       
    */
  Wss.subscribe(UsersSubscription, {
    data: this.handleUser,
  });
  /**
    *   ,     
    */
  Wss.subscribe(MessagesSubscription, {
    data: this.addMessage,
  });
  /**
    *     (   10 )
    */
  Api.query({
    query: InitialChatData,
  }).then(({ data }) => {
    this.users = data.usersList.items;
    this.messages = data.messagesList.items;
  });
  /**
    *     ,   
    */
  window.onbeforeunload = this.closeChat;
},
/**
  *   ,    .
  */
beforeDestroy() {
  this.closeChat();
},
};


طرق المكونات



نحتاج إلى إضافة بعض الطرق لمعالجة كل استدعاء / استجابة API ( createMessage، addMessage، closeChat، إلخ). سيتم تخزين كل منهم في كائن الأسلوب لمكوننا.

من الضروري

ملاحظة شيء واحد: معظم الطفرات لا تنتظر ولا تتعامل مع الإجابات. هذا لأن لدينا اشتراكات تتعقب هذه الطفرات. بعد الإطلاق الناجح ، تتم معالجة بيانات الحدث من خلال الاشتراك.

معظم

هذه الأساليب تتحدث عن نفسها. على أي حال ، اقرأ التعليقات في الكود التالي.



/*  ... */

export default {
/*   ... */
methods: {
  /**
    *   ,     .
    */
  createUser() {
    Api.mutate({
      mutation: CreateUser,
      variables: {
        email: this.me.email,
      },
    });
  },
  /**
    *     ID.
    */
  deleteUser() {
    Api.mutate({
      mutation: DeleteUser,
      variables: { id: this.me.id },
    });
  },
  /**
    *        ,   
*           
* .
*
*    ,      ,  
*   ,   .
    */
  handleUser({
    data: {
      Users: { mutation, node },
    },
  }) {
    ({
      create: this.addUser,
      delete: this.removeUser,
    }[mutation](node));
  },
  /**
    *      users,  , *     .
    */
  addUser(user) {
    if (this.me.email === user.email) {
      this.me = user;
    }
    this.users.push(user);
  },
  /**
    *     users  ID.
    */
  removeUser(user) {
    this.users = this.users.filter(
      (p) => p.id != user.id
    );
  },
  /*    */
  createMessage() {
    Api.mutate({
      mutation: CreateMessage,
      variables: {
        id: this.me.id,
        content: this.newMessage,
      },
    }).then(() => (this.newMessage = ""));
  },
  /**
    *        .  * ,    ,       *.
    */
  addMessage({
    data: {
      Messages: { node },
    },
  }) {
    this.messages.push(node);
  },
  /**
    *        .          beforeDestroy     .
    */
  closeChat () {
    /*     */
    Wss.close()
    /*   */
    this.deleteUser();
    /*     */
    this.me = { me: { email: '' } }
  }
},
/*  ... */
}


قالب مكون



أخيرًا وليس آخرًا ، لدينا مكون GroupChat.vue.

هناك

الآلاف من البرامج التعليمية الرائعة حول كيفية إنشاء واجهات مستخدم جميلة. هذا ليس واحد منهم يتطابق النمط

التالي

لجعلها جميلة أم لا ، الأمر متروك لك. بعد قولي هذا ، دعنا ننتقل بسرعة إلى العلامات الرئيسية التي طبقناها هنا.

كما

هو الحال



<template>
<div id="app">
  <!--
           ,     .      ..
    -->
  <div v-if="me.id" class="chat">
    <div class="header">
      <!--
           ,      ,  ,     ,   .
        -->
      {{ users.length }} Online Users
      <!--
           ,   closeChat..
        -->
      <button @click="closeChat">Leave Chat</button>
    </div>
    <!--
     ,      ,      div.  ,         ,     me.
      -->
    <div
      :key="index"
      v-for="(msg, index) in messages"
      :class="['msg', { me: msg.participant.id === me.id }]"
    >
      <p>{{ msg.content }}</p>
      <small
        ><strong>{{ msg.participant.email }}</strong> {{ msg.createdAt
        }}</small
      >
    </div>
    <!--
      newMessage.
      -->
    <div class="input">
      <input
        type="text"
        placeholder="Say something..."
        v-model="newMessage"
      />
      <!--
           ,    createMessage.
        -->
      <button @click="createMessage">Send</button>
    </div>
  </div>
  <!--
          .     ,   createUser.
    -->
  <div v-else class="signup">
    <label for="email">Sign up to chat!</label>
    <br />
    <input
      type="text"
      v-model="me.email"
      placeholder="What's your email?"
      @blur="createUser"
      required
    />
  </div>
</div>
</template>


والآن تم بناء الدردشة العامة. إذا فتحته على شبكتك المحلية ، يمكنك البدء في إرسال الرسائل واستلامها. ومع ذلك ، لإثبات أن هذه دردشة جماعية حقيقية ، افتح نوافذ متعددة وشاهد تقدم المحادثة.



7. الاستنتاج والاختبار



في هذا البرنامج التعليمي ، اكتشفنا كيف يتيح لنا استخدام أدوات التطوير الحديثة إنشاء تطبيقات واقعية في دقائق.



أرجو أن تعلم أيضا كيفية تهيئة ApolloClientو SubscriptionClientتنفيذ استعلامات GraphQL، والطفرات والاشتراكات بكفاءة في مساحة العمل 8base، وكذلك قليلا عن VueJS.



سواء كنت تعمل على لعبة محمولة أو برامج مراسلة أو تطبيقات إعلام أو مشاريع أخرى تتطلب بيانات في الوقت الفعلي ، فإن الاشتراكات تعد أداة رائعة. والآن بدأنا للتو في النظر فيها.



أنشئ تطبيق دردشة باستخدام 8base



8base عبارة عن واجهة خلفية بدون خادم جاهزة للاستخدام كخدمة تم إنشاؤها بواسطة المطورين للمطورين. تتيح منصة 8base للمطورين إنشاء تطبيقات سحابية مذهلة باستخدام JavaScript و GraphQL. تعرف على المزيد حول منصة 8base هنا .



All Articles