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:



  • 8base  - Verwaltete GraphQL-API
  • VueJS  - JavaScript-Framework


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