So erstellen Sie eine Chat-App in zwanzig Minuten

Bild



Mein Vater erinnert mich gerne daran, dass er als Computeringenieur in den 1970er Jahren " Programmierer war, bevor Programmieren in Mode war ". Er zeigte sogar ein paar Mal alte Fortran- und COBOL-Skripte. Nachdem ich diesen Code gelesen habe, kann ich mit Sicherheit sagen, dass das Programmieren heute definitiv cooler ist .



Ein Kennzeichen moderner Programmiersprachen und Entwicklungsumgebungen ist, wie viel weniger Code ein Entwickler schreiben muss. Durch die Verwendung von Hochsprachen zusammen mit den vielen verfĂŒgbaren APIs, Open Source-Paketen und kostenpflichtigen Diensten können Anwendungen - auch solche mit komplexen Anforderungen - relativ schnell erstellt werden.



Ein Vergleich, der die Entwicklung der Softwareentwicklung zeigt, ist die Konstruktion. Es war einmal, als der Bau eines Hauses mit dem FÀllen von BÀumen auf Ihrem GelÀnde begann. Materialien, Werkzeuge und Methoden erschienen jedoch schnell, so dass der Bau schneller abgeschlossen wurde, Objekte stÀrker wurden und die Arbeiter von einigen elementaren Aufgaben befreit wurden.



Wie viele Wolkenkratzer wĂŒrden gebaut, wenn die Bauherren ihren eigenen Stahl abbauen wĂŒrden?



Softwareentwickler, die bis heute weiterarbeiten, fĂ€llen zu Beginn ihrer Karriere "ihre eigenen BĂ€ume". Gleichzeitig haben beispiellose Innovationen des letzten Jahrzehnts dazu gefĂŒhrt, dass sich die Softwareindustrie Ă€hnlich wie das Baugewerbe zu entwickeln begann.



Einfach ausgedrĂŒckt, moderne Entwickler verfĂŒgen jetzt ĂŒber die Tools, Techniken und Best Practices, um Projekte schneller abzuschließen, stabile Anwendungen zu erhalten und Entwickler vor einfachen Aufgaben zu bewahren.



So erstellen Sie eine Chat-App



Lassen Sie uns schnell etwas erstellen, das frĂŒher Tage oder Wochen gedauert hat. Wir werden eine öffentliche Chatroom-Anwendung erstellen, die WebSockets fĂŒr Echtzeitnachrichten verwendet.



WebSockets werden von allen modernen Browsern nativ unterstĂŒtzt . Unser Ziel ist es jedoch herauszufinden, welche Tools wir bei der Arbeit verwenden können, und sie nicht neu zu erfinden . In diesem Sinne werden wir die folgenden Technologien verwenden:





Das Starterprojekt und die vollstÀndige README-Datei finden Sie in diesem GitHub-Repository . Wenn Sie nur die fertige Anwendung sehen möchten, werfen Sie einen Blick auf den Zweig des öffentlichen Chatrooms.



DarĂŒber hinaus erklĂ€rt das folgende Video (auf Englisch) jeden Schritt ausfĂŒhrlicher.



Lasst uns beginnen.



Sieben Schritte zum Erstellen einer Chat-Anwendung:



1. Projekteinrichtung



Klonen Sie das Starterprojekt und wechseln Sie in das Gruppenchat-Verzeichnis. Sie können selbst entscheiden, ob Sie Garn oder npm zum Installieren von ProjektabhÀngigkeiten verwenden möchten. In jedem Fall benötigen wir alle in der Datei package.json angegebenen NPM-Pakete.



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


Um mit der GraphQL-API zu interagieren, mĂŒssen drei Umgebungsvariablen eingerichtet werden. Erstellen Sie mit dem folgenden Befehl eine .env.local-Datei im Stammverzeichnis, und die Vue-App legt automatisch die Umgebungsvariablen fest, die wir dieser Datei nach der Initialisierung hinzugefĂŒgt haben. Beide Werte und sollten nicht geĂ€ndert werden. Sie mĂŒssen nur den Wert einstellen . Wenn Sie ĂŒber einen 8base-Arbeitsbereich verfĂŒgen, mit dem Sie mithilfe unseres Lernprogramms eine Chat-Anwendung erstellen möchten, aktualisieren Sie die Datei .env.local mit Ihrer Arbeitsbereich-ID. Wenn nicht, rufen Sie die Arbeitsbereich-ID ab, indem Sie die Schritte 1 und 2 in 8base Quickstart ausfĂŒhren .



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. Schema importieren



Jetzt mĂŒssen wir die Serverseite vorbereiten. Im Stammverzeichnis dieses Repositorys sollten Sie die Datei finden chat-schema.json. Um es in den Arbeitsbereich zu importieren, mĂŒssen Sie nur die 8base-Befehlszeile installieren und sich anmelden und dann die Schemadatei importieren.



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


3. API-Zugriff



Die letzte Aufgabe fĂŒr das Backend besteht darin, den öffentlichen Zugriff auf die GraphQL-API zu ermöglichen.



In der 8base Konsole gehen Sie zu App Services > Roles > Guest. Aktualisieren Sie die Berechtigungen, die sowohl fĂŒr BeitrĂ€ge als auch fĂŒr Benutzer festgelegt wurden, um entweder ĂŒberprĂŒft oder als Alle DatensĂ€tze festgelegt zu werden (siehe Abbildung unten).



Die Rolle "Gast" bestimmt, was der Benutzer tun darf, der eine nicht authentifizierte API-Anforderung stellt.



Bild

Rolleneditor in der 8base-Konsole.



4. Schreiben von GraphQL-Abfragen



In diesem Schritt definieren und schreiben wir alle GraphQL-Abfragen, die wir fĂŒr unsere Chat-Komponente benötigen. Dies hilft uns zu verstehen, welche Daten wir mithilfe der API lesen, erstellen und anhören (ĂŒber WebSockets).



Der folgende Code sollte in eine Datei eingefĂŒgt werden src / utils / graphql.js. Lesen Sie die Kommentare ĂŒber jeder exportierten Konstante, um zu verstehen, was jede Abfrage bewirkt.




/* 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. Konfigurieren des Apollo-Clients fĂŒr Abonnements



Nachdem unsere GraphQL-Abfragen geschrieben wurden, ist es Zeit, unsere API-Module einzurichten.



Lassen Sie uns zunĂ€chst den API-Client ApolloClientmit den erforderlichen Standardeinstellungen behandeln. FĂŒr createHttpLinkuns stellen wir unseren vollstĂ€ndig geformten Arbeitsbereich-Endpunkt bereit. Dieser Code ist in 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,    .


Dann werden wir uns mit subscriptions-transport-wsund mit dem Abonnement-Client befassen isomorphic-ws. Dieser Code ist etwas lÀnger als der vorherige, daher lohnt es sich, sich die Zeit zu nehmen, um die Kommentare im Code zu lesen.



Wir initialisieren SubscriptionClientmit unserem WebSockets-Endpunkt und workspaceIdin Parametern connectionParams. Wir verwenden dann diese eine subscriptionClientvon zwei Methoden, die im Standardexport definiert sind: subscribe()und close().



subscribeermöglicht es uns, neue Abonnements mit Daten und FehlerrĂŒckrufen zu erstellen. Mit der Schließmethode können wir die Verbindung schließen, wenn wir den Chat verlassen.



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. Schreiben einer Vue-Komponente



Wir haben jetzt alles, was wir brauchen, um einen öffentlichen Chat zu erstellen. Es gibt nur noch eine Komponente zum Schreiben GroupChat.vue.



Laden Sie die Komponente mit Garnaufschlag und fahren Sie fort.



Ein wichtiger Hinweis: Jeder hat seine eigene Vorstellung von Schönheit, daher habe ich nur die minimalen Stile erstellt, die erforderlich sind, damit die Komponente funktionsfÀhig ist.



Komponentenskript



Zuerst mĂŒssen wir unsere Module, einfachen Stile und GraphQL-Abfragen importieren. Das alles ist in unserem src / utils.

Deklarieren Sie die folgenden Importe in 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";


Komponentendaten



Wir können definieren, welche Dateneigenschaften wir in der Datenfunktion unserer Komponente verwenden möchten. Wir benötigen lediglich eine Möglichkeit, Chat-Benutzer, Nachrichten, den Namen des "aktuellen" Benutzers und alle noch nicht gesendeten Nachrichten zu speichern. Diese Eigenschaften können wie folgt hinzugefĂŒgt werden:



/* imports ... */

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


Lebenszyklus-Haken



Unsere Lifecycle-Hooks laufen an verschiedenen Punkten im Leben einer Vue-Komponente. Zum Beispiel, wenn es gemountet oder aktualisiert wird. In diesem Fall interessieren wir uns nur fĂŒr die Erstellung und beforeDestroyKomponente. In solchen FĂ€llen möchten wir entweder die Chat-Abonnements öffnen oder schließen.



/* ... */

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();
},
};


Komponentenmethoden



Wir brauchen ein paar Methoden hinzufĂŒgen jeden Anruf / API - Antwort zu verarbeiten ( createMessage, addMessage, closeChat, etc.). Alle von ihnen werden im Methodenobjekt unserer Komponente gespeichert. Eines

ist zu

Dies liegt daran, dass wir Abonnements haben, die diese Mutationen verfolgen. Nach einem erfolgreichen Start werden Ereignisdaten vom Abonnement verarbeitet.

Die meisten

dieser Methoden sprechen fĂŒr sich. Lesen Sie auf jeden Fall die Kommentare im folgenden Code.



/*  ... */

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: '' } }
  }
},
‍
/*  ... */
}


Komponentenvorlage



Zu guter Letzt haben wir eine Komponente GroupChat.vue.

Es gibt

Tausende großartiger Tutorials zum Erstellen schöner BenutzeroberflĂ€chen. Dies ist keiner von ihnen.

Das folgende

Muster entspricht den Mindestanforderungen fĂŒr die Chat-Anwendung. Es schön zu machen oder nicht, liegt bei Ihnen. Lassen Sie uns jedoch kurz auf das SchlĂŒssel-Markup eingehen, das wir hier implementiert haben. Lesen Sie

wie





<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>


Und jetzt ist der öffentliche Chat aufgebaut. Wenn Sie es in Ihrem lokalen Netzwerk öffnen, können Sie Nachrichten senden und empfangen. Um jedoch zu beweisen, dass dies ein echter Gruppenchat ist, öffnen Sie einige Fenster und beobachten Sie den Fortschritt der Konversation.



7. Schlussfolgerung und PrĂŒfung



In diesem Tutorial haben wir untersucht, wie wir mithilfe moderner Entwicklungstools in wenigen Minuten reale Anwendungen erstellen können.



Ich hoffe, Sie haben auch gelernt, wie Sie GraphQL-Abfragen, Mutationen und Abonnements effizient in einem 8base-Arbeitsbereich initialisieren ApolloClientund SubscriptionClientausfĂŒhren können, sowie ein wenig ĂŒber VueJS.



UnabhĂ€ngig davon, ob Sie an einem Handyspiel, Messenger, Benachrichtigungs-Apps oder anderen Projekten arbeiten, fĂŒr die Echtzeitdaten erforderlich sind, sind Abonnements ein hervorragendes Tool. Und jetzt haben wir gerade begonnen, sie zu betrachten.



Erstellen Sie eine Chat-App mit 8base



8base ist ein schlĂŒsselfertiges serverloses Backend als Service, der von Entwicklern fĂŒr Entwickler entwickelt wurde. Mit der 8base-Plattform können Entwickler mit JavaScript und GraphQL beeindruckende Cloud-Anwendungen erstellen. Erfahren Sie mehr ĂŒber die 8base Plattform hier .



All Articles