PubNub vs Pusher mencipta apl pemesejan masa nyata dalam React

DDD
Lepaskan: 2024-09-13 22:18:02
asal
650 orang telah melayarinya

Data masa nyata adalah salah satu tiang teras untuk aplikasi moden hari ini. Mempunyai sistem yang mampu menghantar maklumat dwiarah membolehkan kami sentiasa mengikuti perkembangan terkini dengan pelbagai maklumat. Contoh sedemikian boleh termasuk aplikasi pemesejan, analitik data untuk papan pemuka yang digunakan untuk data kewangan, paparan kepala (HUD) yang digunakan dalam aplikasi tambahan dan maya. Seperti juruterbang pejuang yang menerbangkan pesawat atau pengguna kasual menggunakan set kepala Apple Vision Pro. Terdapat kes penggunaan yang tidak berkesudahan untuk teknologi ini.

Apabila bercakap tentang aplikasi IM am, mempunyai keupayaan untuk bercakap dengan seseorang dalam masa nyata membuka pintu kepada begitu banyak kemungkinan unik. Dunia kita telah menjadi lebih berhubung hasil daripada keupayaan baharu ini. Dalam artikel hari ini kita akan mempelajari semua tentang pemesejan semasa kita membina aplikasi pemesejan masa nyata. Aplikasi ini akan dapat menyambung ke dua platform aplikasi masa nyata yang berbeza iaitu Pusher dan PubNub.

Aplikasi kami hampir sama dengan versi asas, aplikasi WhatsApp dan Telegram. Anda boleh membuka lebih daripada satu pelayar web atau tab penyemak imbas dan ini akan memberi kami kuasa untuk log masuk dengan berbilang pengguna. Dengan cara ini kami boleh menguji sembang kumpulan antara lebih daripada seorang pengguna seperti yang anda lakukan jika ia adalah aplikasi sembang sebenar.

Di bawah anda boleh melihat rupa papan pemuka utama kami, kerana anda boleh lihat terdapat butang untuk menavigasi ke kedua-dua versi apl pemesejan kami:

PubNub vs Pusher creating a realtime messaging app in React

Dan di sini anda boleh melihat rupa versi PubNub apl kami dalam tangkapan skrin ini. Ia digambarkan oleh pengepala biru:
PubNub vs Pusher creating a realtime messaging app in React

Versi Pusher mempunyai pengepala hijau dan dengan ini anda akan dapat membezakan secara visual antara kedua-duanya:
PubNub vs Pusher creating a realtime messaging app in React

Baiklah, dengan pengenalan pantas kami selesai, kami kini boleh melihat dengan lebih teliti sambil melihat bagaimana ia berbeza antara satu sama lain. Pangkalan kod untuk aplikasi pemesejan boleh didapati di GitHub saya di sini: https://github.com/andrewbaisden/realtime-chat-app.

Prasyarat

Sebelum kami bermula, lihat prasyarat ini dan pastikan anda telah menyediakan segala-galanya sebelum kami bermula.

  • Nod dan npm dipasang.
  • IDE dipasang seperti Visual Studio Code
  • Akaun di PubNub
  • Akaun di Pusher

PubNub lwn Pusher

Kedua-dua platform berkongsi banyak persamaan tetapi terdapat beberapa perbezaan ketara yang menjadikannya mudah untuk dibezakan. Salah satu yang utama ialah hakikat bahawa seni bina mereka tidak sama.

Perbezaan Seni Bina

Dalam kes PubNub ia adalah platform awan yang boleh menjaga penstriman data dan mesej. Terdapat kependaman yang sangat rendah sebagai ketersediaan perkhidmatan yang baik kerana ia tersedia di seluruh dunia. Skala dan infrastruktur dikendalikan dengan baik oleh platform supaya pembangun bebas untuk mengusahakan perkara yang penting iaitu projek.

Kini dengan Pusher mereka menawarkan pilihan penggunaan yang berbeza yang dihoskan sendiri dan dihoskan awan. Apabila menggunakan yang dihoskan sendiri, Pusher mampu berjalan pada perkakasan atau perisian tersuai anda sendiri dan ini memberikan anda begitu banyak kebebasan. Mengenai penyelesaian yang dihoskan awan, anda boleh mengharapkan perkhidmatan yang serupa dengan PubNub.

Perbandingan API dan SDK

Apabila kita membandingkan ciri di sana, kita dapat melihat bahawa kedua-duanya menawarkan SDK dan perpustakaan yang disokong oleh pelbagai bahasa pengaturcaraan. Ini termasuk JavaScript, Python, Java, Swift, Ruby dan banyak lagi. Saluran tersedia pada kedua-dua platform dan ini membolehkan kami menerbitkan dan melanggan pelbagai aliran data. Kehadiran ialah satu lagi pilihan dan dengan ini kami dapat melihat status dalam talian dan luar talian untuk semua pengguna dalam masa nyata pada saluran berbeza yang kami sediakan. Berkenaan dengan sejarah mesej, ia adalah cerita yang serupa dan perkara yang sama berlaku untuk pemberitahuan tolak.

Satu lagi aspek yang hebat ialah hakikat bahawa mereka kaya dengan ciri dan dokumentasi yang sangat lengkap menjadikannya sangat mudah untuk dipelajari dan mengetahui dengan pantas tentang ciri-ciri berbeza yang ditawarkan. Anda boleh mendapatkan dokumentasi masing-masing di bawah:

Dokumentasi PubNub: PubNub
Dokumentasi Penolak: Penolak

Melaksanakan Apl Pemesejan Masa Nyata dengan React

Masa untuk mengusahakan permohonan kami! Mula-mula pastikan anda mempunyai akaun di PubNub dan Pusher terlebih dahulu, kami akan segera melalui proses membuat akaun di kedua-dua platform sekarang, jadi ikuti jika anda belum membuat akaun lagi.

Mencipta akaun di PubNub

Bermula dengan PubNub pergi ke halaman utama tapak web dan klik pada butang di bahagian atas di sebelah kanan untuk mencuba secara percuma seperti yang ditunjukkan di bawah.

PubNub vs Pusher creating a realtime messaging app in React

Kini anda sepatutnya melihat halaman pendaftaran jadi teruskan dan gunakan borang untuk membuat akaun anda.

PubNub vs Pusher creating a realtime messaging app in React

Ok sekarang dengan akaun anda yang dicipta, akses ke papan pemuka sepatutnya boleh dilakukan. Gunakan menu untuk pergi ke bahagian Keysets dan kemudian cari apl anda dan keysetnya. Ini juga merupakan bahagian di mana anda harus membuat apl jika belum ada apl.

Kunci API anda seharusnya boleh dilihat sekarang jadi pastikan pilihan kehadiran dan kegigihan dihidupkan kerana kami memerlukan ini untuk menjejak pengguna dan data.

PubNub vs Pusher creating a realtime messaging app in React

Mencipta akaun di Pusher

Oleh itu, kami telah selesai dengan akaun PubNub kami buat masa ini, mari kita bekerja pada akaun Pusher kami. Seperti sebelum pergi ke tapak web dan klik butang daftar di sudut kanan atas halaman.

PubNub vs Pusher creating a realtime messaging app in React

Sekarang pada skrin berikut, gunakan borang untuk membuat akaun seperti yang anda lihat di sini.

PubNub vs Pusher creating a realtime messaging app in React

Saluran mesti dibuat jadi pada halaman papan pemuka pilih butang urus untuk berbuat demikian.

PubNub vs Pusher creating a realtime messaging app in React
Pada halaman seterusnya yang sepatutnya menjadi skrin saluran, buat apl menggunakan butang buat apl seperti yang ditunjukkan dalam tangkapan skrin ini.

PubNub vs Pusher creating a realtime messaging app in React

Sekarang kita boleh beralih ke borang dan seperti yang anda lihat dalam contoh ini konfigurasi harus disesuaikan untuk kes penggunaan anda.

PubNub vs Pusher creating a realtime messaging app in React

Jadi apabila peringkat itu telah selesai, halaman saluran harus dipaparkan seperti di sini.
PubNub vs Pusher creating a realtime messaging app in React
Klik pada Kunci Apl yang terdapat dalam menu bar sisi dan kemudian anda akan mendapat akses kepada kunci API yang anda perlukan kemudian.

PubNub vs Pusher creating a realtime messaging app in React

Bagus jadi fasa persediaan akaun kini telah selesai, di bahagian seterusnya kami akan memulakan kod untuk apl kami. Langkah pertama ialah membuat seni bina projek dengan folder dan lain-lain... Saya meneruskan dan mencipta skrip salin dan tampal untuk baris arahan supaya kita tidak perlu menulis semua arahan secara manual. Mulakan dengan mencipta projek pada komputer anda yang dipanggil realtime-chat-app dan kemudian pergi ke lokasi menggunakan baris arahan.

Menyediakan aplikasi React

Gunakan Next.js untuk mencipta projek dan kemudian gunakan skrip shell untuk menyediakan projek.

Kami bermula dengan menjalankan arahan ini untuk mencipta projek Next.js:

npx create-next-app client
Salin selepas log masuk

Kini pada skrin konfigurasi adalah penting untuk memilih Tailwind CSS dan Penghala Apl kerana kami memerlukan pilihan tersebut dalam projek ini.

Di sini ialah skrip shell untuk mencipta fail dan folder dan memasang kebergantungan hanya jalankannya di dalam folder yang sama, ia akan secara automatik dimasukkan ke dalam folder klien. Jika anda sudah berada dalam folder klien maka anda boleh meninggalkan baris pertama dalam skrip.

cd client
npm install @pubnub/react-chat-components axios pubnub pubnub-react pusher pusher-js
touch .env.local
cd src/app
mkdir components pubnub pusher
touch components/ChatInterface.js components/ChatMessage.js components/ChatPubNub.js components/ChatPusher.js components/DashboardButton.js components/Header.js components/UserLogin.js pubnub/page.js pusher/page.js
cd ../../..
mkdir server
cd server
npm init -y
npm install express cors pusher dotenv
touch index.js .env
cd ..
Salin selepas log masuk

Terdapat banyak perkara yang berlaku di sini jadi mari lihat apa yang dilakukan skrip ini:

  • Memasang kebergantungan untuk projek kami yang termasuk pakej dan pakej PubNub dan Pusher
  • Mencipta fail pembolehubah persekitaran untuk kunci API kami
  • Membuat fail, folder dan komponen untuk keseluruhan apl kami
  • Menyediakan pelayan bahagian belakang yang Pusher perlukan untuk akses API
  • Membina fail pelayan untuk tujuan penghalaan dan logik

Lihat pada ambil skrin ini, ini adalah bagaimana projek kami sepatutnya kelihatan dalam IDE anda:

PubNub vs Pusher creating a realtime messaging app in React

The hard work is done that build script did most of the work we just have to add the code to the files.

Right our first file is the globals.css file so clear all the code in that file and replace it with what is shown here:

@tailwind base;
@tailwind components;
@tailwind utilities;

body {
  background-color: rgb(15 23 42);
}
Salin selepas log masuk

Code cleanup has been done in this file and now we have a background colour for our application.

Onto the layout.css file. Continuing from what we just did replace all the code with this new code:

import { Ubuntu } from 'next/font/google';
import './globals.css';

const ubuntu = Ubuntu({
  subsets: ['latin'],
  weight: ['300', '400', '500', '700'],
});

export const metadata = {
  title: 'Realtime Chat App',
  description: 'Generated by create next app',
};

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body className={ubuntu.className}>{children}</body>
    </html>
  );
}
Salin selepas log masuk

Ubuntu is now the default font in our application.

All thats left in this section is to replace all of the code in our next.config.mjs file with this code:

/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [
      {
        hostname: 'res.cloudinary.com',
      },
    ],
  },
};

export default nextConfig;
Salin selepas log masuk

Cloudinary was added as an image host so now we can use it throughout our app.

And with that the project setup phase is done so in the next section we will work on the main files for our codebase. First we will do PubNub and then we will do Pusher.

Integrating PubNub

The initilisation and configuration part will be the first one to tackle. You must sign into your PubNub account, and find the application you made at the start. Locate your Keysets as well as the Publish and Subscribe Keys. Now put them inside of the .env.local file in the project.

Here is an example of where they should be put:

NEXT_PUBLIC_PUBNUB_PUBLISH_KEY=your-publish-key
NEXT_PUBLIC_PUBNUB_SUBSCRIBE_KEY=your-subscribe-key
Salin selepas log masuk

Time to add some code to our components/ChatPubNub.js file, and this is the file where we can find the main code for subscribing to channels, handling the presence and publishing our message.

Put the code you see here into the components/ChatPubNub.js file:

import { useState, useEffect, useRef } from 'react';
import PubNub from 'pubnub';
import ChatInterface from './ChatInterface';

export default function ChatPubNub({ activeUser }) {
  const [chats, setChats] = useState([]);
  const [count, setCount] = useState(1);
  const bottomRef = useRef(null);

  let pubnub;
  const channelName = 'presence-chatroom';

  useEffect(() => {
    pubnub = new PubNub({
      publishKey: process.env.NEXT_PUBLIC_PUBNUB_PUBLISH_KEY,
      subscribeKey: process.env.NEXT_PUBLIC_PUBNUB_SUBSCRIBE_KEY,
      uuid: activeUser,
    });

    pubnub.addListener({
      message: (messageEvent) => {
        const chat = messageEvent.message;
        setChats((prevChats) => [...prevChats, chat]);
      },
    });

    const presenceChannelName = `${channelName}-pnpres`;

    pubnub.subscribe({
      channels: [channelName],
      withPresence: true,
      presenceChannels: [presenceChannelName],
    });

    const scrollToBottom = () => {
      bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
    };

    scrollToBottom();

    return () => {
      pubnub.unsubscribeAll();
    };
  }, [chats, activeUser, count]);

  const handleKeyUp = (evt) => {
    const value = evt.target.value;
    if (evt.keyCode === 13 && !evt.shiftKey) {
      const chat = { user: activeUser, message: value, timestamp: +new Date() };
      evt.target.value = '';
      pubnub.publish({
        channel: channelName,
        message: chat,
      });
    }
  };

  return activeUser ? (
    <>
      <ChatInterface
        activeUser={activeUser}
        count={count}
        chats={chats}
        handleKeyUp={handleKeyUp}
        bottomRef={bottomRef}
      />
    </>
  ) : null;
}
Salin selepas log masuk

Here is a quick explanation of what our code does in this file. We can do subscriptions to channels, publish messages to different channels as well as handle the overall presence information. With these capabilities our app will function a lot like a group chat and with presence switched on we can see how many users are online in real-time.

We can work on our next file now which is the components/ChatInterface.js so add this code to it:

import ChatMessage from './ChatMessage';

export default function ChatInterface({
  activeUser,
  count,
  chats,
  handleKeyUp,
  bottomRef,
}) {
  return (
    <div className="flex">
      <aside className="w-64 min-w-64 bg-slate-800 p-2">
        <h1 className="text-lg text-white">Chats</h1>
        <div className="flex justify-between mt-2">
          <div className="flex">
            <div className="rounded-full bg-slate-100 h-10 w-10 mr-2"></div>
            <div className="text-sm">
              <p className="text-white">John</p>
              <p className="text-slate-400">Hello world</p>
            </div>
          </div>
          <div className="text-sm text-slate-400">Friday</div>
        </div>
      </aside>
      <section className="grow">
        <div className="bg-zinc-800 p-2">
          <div className="flex">
            <div className="rounded-full bg-slate-100 h-10 w-10 mr-2"></div>
            <div>
              <h1 className="text-2xl text-white">{activeUser}</h1>
              <span className="text-gray-300">users online: {count}</span>
            </div>
          </div>
        </div>
        <div className="bg-zinc-900 p-2 overflow-y-auto h-80 max-h-80 text-white">
          {chats.map((chat, index) => {
            const previous = Math.max(0, index - 1);
            const previousChat = chats[previous];
            const position = chat.user === activeUser ? 'right' : 'left';
            const isFirst = previous === index;
            const inSequence = chat.user === previousChat.user;
            const hasDelay =
              Math.ceil(
                (chat.timestamp - previousChat.timestamp) / (1000 * 60)
              ) > 1;
            return (
              <div key={index}>
                {(isFirst || !inSequence || hasDelay) && (
                  <div>
                    <span>{chat.user || 'Anonymous'}</span>
                  </div>
                )}

                <ChatMessage message={chat.message} position={position} />
              </div>
            );
          })}
          <div ref={bottomRef} />{' '}
        </div>
        <div className="w-full bg-zinc-800 p-2">
          <textarea
            onKeyUp={handleKeyUp}
            placeholder="Enter a message"
            className="w-full block rounded mt-2 mb-2 p-2 text-white bg-zinc-600"
          ></textarea>
        </div>
      </section>
    </div>
  );
}
Salin selepas log masuk

Our component displays the UI for our messaging chat interface. There is a section for messaging, sending messages and a sidebar, which could hold users when they are in the group.

The next component is for the components/ChatMessage.js file and this has our chat message interface.

Add this code to the file:

export default function ChatMessage({ message }) {
  return (
    <div>
      <div className="mt-4 mb-4">
        <span className="bg-zinc-600 p-2 rounded">{message}</span>
      </div>
    </div>
  );
}
Salin selepas log masuk

Chat bubbles should become possible thanks to this component whenever we use the chat to send messages to users.

Dashboard buttons is what we require next so add this code to our components/DashboardButton.js file:

import Link from 'next/link';
import Image from 'next/image';

export default function DashboardButton({ url, img, alt }) {
  return (
    <>
      <Link href={url}>
        <div className="rounded mr-4 bg-slate-50 hover:bg-slate-200 h-96 w-96 text-center flex items-center justify-center drop-shadow-lg uppercase">
          <Image src={img} height={200} width={200} alt={alt} />
        </div>
      </Link>
    </>
  );
}
Salin selepas log masuk

We can now easily navigate between the PubNub and Pusher versions of our real-time messaging chat app using these reusable buttons.

Ok the navigation component is next and this is for our main header. Put this code in our file at components/Header.js:

import Link from 'next/link';

export default function Header() {
  return (
    <>
      <nav className="bg-white flex justify-around p-8 mb-4 font-bold">
        <Link href={'/'}>Dashboard</Link>
        <Link href={'/pusher'}>Pusher Chat App</Link>
        <Link href={'/pubnub'}>PubNub Chat App</Link>
      </nav>
    </>
  );
}
Salin selepas log masuk

All our page routes are easily able to be navigated using this header component which has page links.

The login screen is next and this is the code our file at components/UserLogin.js desires:

import { useState } from 'react';
import ChatPubNub from '../components/ChatPubNub';
import ChatPusher from '../components/ChatPusher';

export default function UserLogin({ bgColor, appName }) {
  const [user, setUser] = useState(null);

  const handleKeyUp = (evt) => {
    if (evt.keyCode === 13) {
      const newUser = evt.target.value;
      setUser(newUser);
    }
  };
  return (
    <>
      <main>
        <div>
          <section>
            <div className={`p-4 ${bgColor} text-slate-100`}>
              <span>
                {user ? (
                  <span className="flex justify-between text-white">
                    <span>
                      {user} <span>is online</span>
                    </span>
                    <span>{appName}</span>
                  </span>
                ) : (
                  <span className="text-2xl text-white">
                    What is your name?
                  </span>
                )}
              </span>
              {!user && (
                <input
                  type="text"
                  onKeyUp={handleKeyUp}
                  autoComplete="off"
                  className="w-full block rounded mt-2 mb-2 p-2 text-black"
                />
              )}
            </div>
          </section>
          {appName === 'PubNub Chat' ? (
            <section>{user && <ChatPubNub activeUser={user} />}</section>
          ) : (
            <section>{user && <ChatPusher activeUser={user} />}</section>
          )}
        </div>
      </main>
    </>
  );
}
Salin selepas log masuk

Its a pretty straightforward login screen component whereby a user can choose a name and then they get redirected to the messaging app. There is logic to check which app a user is using and it automatically sends the user to the right chat interface for that version of the app.

Lets do the pubnub/page.js route file now and add this code to it:

'use client';
import Header from '../components/Header';
import UserLogin from '../components/UserLogin';

export default function PubNub() {
  return (
    <div>
      <Header />
      <UserLogin bgColor={'bg-sky-800'} appName={'PubNub Chat'} />
    </div>
  );
}
Salin selepas log masuk

We can find the main page route for the PubNub version messaging app.

Lastly we must add code to our page.js file in the root folder to complete our application so like before just replace the code with what we have written here:

'use client';
import DashboardButton from './components/DashboardButton';

export default function Home() {
  return (
    <>
      <div className="h-screen flex justify-center items-center">
        <div className="text-center">
          <h1 className="mb-4 text-white text-4xl">Choose a messaging app</h1>
          <div className="grid gap-2 lg:grid-cols-2 md:grid-cols-1 sm:grid-cols-1">
            <DashboardButton
              url={'/pusher'}
              img={
                'https://res.cloudinary.com/d74fh3kw/image/upload/v1715187329/pusher-logo_u0gljx.svg'
              }
              alt="Pusher Logo"
            />
            <DashboardButton
              url={'/pubnub'}
              img={
                'https://res.cloudinary.com/d74fh3kw/image/upload/v1715189173/pubnub-logo-vector_olhbio.png'
              }
              alt="PubNub Logo"
            />
          </div>
        </div>
      </div>
    </>
  );
}
Salin selepas log masuk

Our main dashboard link can be found here which has the buttons for our PubNub and Pusher version of our application.

The PubNub messaging part of our application should be good to go now! Just cd into the client folder if you have not done so already and start the application with the usual Next.js run command:

npm run dev
Salin selepas log masuk

Its worth mentioning that the Pusher part of our application is not going to work yet as we must complete the integrations in the upcoming section. To use the PubNub app go to the login screen, enter a name and hit the enter button and then you will see the messenger chat application screen. You can see your online status and the sidebar has a hard-coded user which is just an example.

To make the application more interactive open more browser tabs or browser windows and sign in with more users. Having a real-time group chat is now possible just like any other messaging app you are familiar with.

In the next section we shall get Pusher up and working.

Integrating Pusher

This section will take less time because we get to reuse a lot of the components we used in the earlier sections. The difference this time around is that Pusher will need to connect to our backend server to work.

Like before we are going to start with the configuration files for our .env.local and .env files in the server and client folders. We need to add the same secrets to the files. Find your application on the Pusher platform and then find the App keys.

The App keys must be added to the env files with the right variables. Take a note of this key difference. Our client .env.local env file must have NEXT_PUBLIC at the start, and the .env file in the server folder does not require it and you can see that in the examples below.

Here is our .env.local file which is in the client folder:

NEXT_PUBLIC_PUBNUB_PUBLISH_KEY=your-publish-key
NEXT_PUBLIC_PUBNUB_SUBSCRIBE_KEY=your-subscribe-key
NEXT_PUBLIC_PUSHER_APP_ID=your-app-id
NEXT_PUBLIC_PUSHER_APP_KEY=your-app-key
NEXT_PUBLIC_PUSHER_APP_SECRET=your-app-secret
NEXT_PUBLIC_PUSHER_APP_CLUSTER=your-cluster
Salin selepas log masuk

And this is the .env file which can be found in the server folder:

PUSHER_APP_ID=your-app-id
PUSHER_APP_KEY=your-app-key
PUSHER_APP_SECRET=your-app-secret
PUSHER_APP_CLUSTER=your-cluster
Salin selepas log masuk

Time to work on the frontend so you know the drill add this code to the components/ChatPusher.js file:

import { useState, useEffect, useRef } from 'react';
import axios from 'axios';
import Pusher from 'pusher-js';
import ChatInterface from './ChatInterface';

export default function ChatPusher({ activeUser }) {
  const [chats, setChats] = useState([]);
  const [count, setCount] = useState(0);
  const bottomRef = useRef(null);

  let channel;
  let pusher;

  useEffect(() => {
    pusher = new Pusher(process.env.NEXT_PUBLIC_PUSHER_APP_KEY, {
      cluster: process.env.NEXT_PUBLIC_PUSHER_APP_CLUSTER,
      useTLS: true,
      channelAuthorization: {
        endpoint: 'http://localhost:8000/auth',
      },
    });

    channel = pusher.subscribe('presence-chatroom');
    channel.bind('new-message', ({ chat = null }) => {
      if (chat) {
        setChats((prevChats) => [...prevChats, chat]);
      }
    });

    channel.bind('pusher:subscription_succeeded', () => {
      updateMemberCount(channel);
    });

    channel.bind('pusher:member_added', () => {
      updateMemberCount(channel);
    });
    channel.bind('pusher:member_removed', () => {
      updateMemberCount(channel);
    });

    const scrollToBottom = () => {
      bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
    };

    scrollToBottom();

    return () => {
      pusher.disconnect();
    };
  }, [chats]);

  const updateMemberCount = (presenceChannel) => {
    const memberCount = Object.keys(presenceChannel.members.members).length;
    console.log('Count people online', memberCount);
    setCount(memberCount);
  };

  const handleKeyUp = (evt) => {
    const value = evt.target.value;
    if (evt.keyCode === 13 && !evt.shiftKey) {
      const chat = { user: activeUser, message: value, timestamp: +new Date() };
      evt.target.value = '';
      axios.post('http://localhost:8000/message', chat);
    }
  };

  return activeUser ? (
    <>
      <ChatInterface
        activeUser={activeUser}
        count={count}
        chats={chats}
        handleKeyUp={handleKeyUp}
        bottomRef={bottomRef}
      />
    </>
  ) : null;
}
Salin selepas log masuk

There are similarities here to our PubNub component which matches this. We can subscribe to the channels, publish different messages and handle the presence. Although all of this is now done via the backend which now also works with basic authentication. Unlike the PubNub version however this version can accurately see how many users are online as well as when users are active, join and leave the group chat.

An authentication route is present for authenticating users and we incorporated a message route for posting all messages to our server.

Our frontend is almost completed just one file remains so add this code to our pusher.page.js file now:

'use client';
import Header from '../components/Header';
import UserLogin from '../components/UserLogin';

export default function Pusher() {
  return (
    <div>
      <Header />
      <UserLogin bgColor={'bg-emerald-800 '} appName={'Pusher Chat'} />
    </div>
  );
}
Salin selepas log masuk

This file ensures that our Pusher version has a working route. All thats left is to get the messaging app up and running when we do the server file next.

Before we do that we should setup our run script in our package.json file so add this script to it:

"scripts": {
"start": "node index.js"
},
Salin selepas log masuk

Alright, last file! Add this code to our index.js file in the server folder so we can complete the backend:

const cors = require('cors');
const Pusher = require('pusher');
const express = require('express');
require('dotenv').config();
const crypto = require('crypto');
const dev = process.env.NODE_ENV !== 'production';
const port = process.env.PORT || 8000;

const pusher = new Pusher({
  appId: process.env.PUSHER_APP_ID,
  key: process.env.PUSHER_APP_KEY,
  secret: process.env.PUSHER_APP_SECRET,
  cluster: process.env.PUSHER_APP_CLUSTER,
  useTLS: true,
});

const server = express();
server.use(cors());
server.use(express.json());
server.use(express.urlencoded({ extended: false }));

const chatHistory = { messages: [] };

server.post('/message', (req, res) => {
  const { user = null, message = '', timestamp = +new Date() } = req.body;
  const chat = { user, message, timestamp };
  chatHistory.messages.push(chat);
  pusher.trigger('presence-chatroom', 'new-message', { chat });
  res.status(200).send('Message sent successfully.');
});
server.post('/messages', (req, res) => {
  res.json({ ...chatHistory, status: 'success' });
});

server.post('/auth', (req, res) => {
  const socketId = req.body.socket_id;
  const channel = req.body.channel_name;
  console.log('Socket and channel', socketId, channel);
  const userId = crypto.randomBytes(8).toString('hex');

  const presenceData = {
    user_id: userId,
    user_info: {
      name: 'Anonymous User',
    },
  };

  const auth = pusher.authorizeChannel(socketId, channel, presenceData);
  res.send(auth);
});

server.listen(port, (err) => {
  if (err) throw err;
  console.log(`Server is running on port: ${port} http://localhost:${port}`);
});
Salin selepas log masuk

Just a quick run through of this file so we can understand how it works. If you don't know its an Express server file which can connect to the Pusher API and it has routes for the authentication, message posting, in addition to getting chat history for all messages.

For connectivity, cors is implemented, so we don't get any of those annoying errors when trying to connect to different servers. The crypto module is used to doing various tasks like hash generation and encrypting and decrypting data.

With our codebase at MVP status, all you have to do is run the backend server in a different terminal window with the following command as shown below:

npm run start
Salin selepas log masuk

So our server will run on port 8000 and you can change this in the server code if need be. Of course our Next.js application runs on port 3000, they need to be on different ports for obvious reasons. You already know how to use the PubNub version, the Pusher version works much the same.

Congratulations you have reached the end of this tutorial and created a working real-time messaging application!

Conclusion

Thats it we have completed the tutorial, learned about both real-time messaging applications and built a working demo application. As you have learned both platforms offer a similar feature set although Pusher has self-hosted and cloud options whereas PubNub offers only the later.

Ultimately your choice of platform will come down to what you make of their pros and cons. They have a free plan, so testing them is pretty easy to do. Pusher has flexible pricing in contrast to PubNubs strict pricing that offers much cheaper starter options priced at $98 compared to $49 for the Pusher startup option.

Atas ialah kandungan terperinci PubNub vs Pusher mencipta apl pemesejan masa nyata dalam React. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:dev.to
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!