Skip to content

Commit

Permalink
Add PubSub example for channels and messages
Browse files Browse the repository at this point in the history
  • Loading branch information
GregHolmes committed Dec 18, 2024
1 parent 31b11d6 commit 78d1ca2
Show file tree
Hide file tree
Showing 26 changed files with 5,190 additions and 0 deletions.
1 change: 1 addition & 0 deletions examples/pub-sub-channel-messages/javascript/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_PUBLIC_ABLY_KEY=
36 changes: 36 additions & 0 deletions examples/pub-sub-channel-messages/javascript/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
39 changes: 39 additions & 0 deletions examples/pub-sub-channel-messages/javascript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Sending and receiving messages in a channel

This folder contains the code for channels and messages (Typescript) - a demo of how you can leverage [Ably Pub/Sub](https://ably.com/docs/products/channels) to join a room to channel and receive messages.

## Getting started

1. Clone the [Ably docs](https://github.com/ably/docs) repository where this example can be found:

```sh
git clone [email protected]:ably/docs.git
```

2. Change directory:

```sh
cd /examples/pub-sub-channel-messages/javascript/
```

3. Rename the environment file:

```sh
mv .env.example .env.local
```

4. In `.env.local` update the value of `VITE_PUBLIC_API_KEY` to be your Ably API key.

5. Install dependencies:

```sh
yarn install
```

6. Run the server:

```sh
yarn run dev
```

7. Try it out by opening two tabs to [http://localhost:5173/](http://localhost:5173/) with your browser to see the result.
22 changes: 22 additions & 0 deletions examples/pub-sub-channel-messages/javascript/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href='https://fonts.googleapis.com/css?family=Inter' rel='stylesheet'>
<link rel="stylesheet" href="src/styles.css" />
<title>Pub/Sub channels and messages</title>
</head>
<body class="font-inter">
<div class="min-h-screen p-8 flex flex-col items-center gap-6">
<button id="publish" class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded">
Publish Random Headline
</button>
<div class="w-full max-w-2xl h-96 border rounded-lg overflow-y-auto bg-white shadow-lg">
<div id="headlines" class="p-4 space-y-2"></div>
</div>
<div id="headlines-remaining" class="text-sm text-gray-500"></div>
</div>
<script type="module" src="src/script.ts"></script>
</body>
</html>
23 changes: 23 additions & 0 deletions examples/pub-sub-channel-messages/javascript/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "pub-sub-channel-messages",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"devDependencies": {
"autoprefixer": "^10.4.20",
"dotenv": "^16.4.5",
"postcss": "^8.4.47",
"tailwindcss": "^3.4.13",
"typescript": "^5.6.3"
},
"dependencies": {
"ably": "^2.3.1",
"nanoid": "^5.0.7",
"vite": "^5.4.2"
}
}
66 changes: 66 additions & 0 deletions examples/pub-sub-channel-messages/javascript/src/script.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import * as Ably from 'ably';
import { nanoid } from 'nanoid';
import './styles.css';

const client = new Ably.Realtime({
clientId: nanoid(),
key: import.meta.env.VITE_PUBLIC_ABLY_KEY as string,
});

let headlines = [
'AI Breakthrough: New Model Achieves Human-Level Understanding in Complex Tasks',
'SpaceX Successfully Launches 100th Mission to Mars',
'Quantum Computing Milestone: 1000 Qubit Processor Unveiled',
'Revolutionary Battery Technology Promises Week-Long Phone Charge',
'Web4 Protocol Introduces Decentralized Neural Networks',
'Flying Cars Get FAA Approval for Urban Transportation',
'Scientists Develop Self-Healing Smartphone Screens',
'Blockchain Technology Revolutionizes Global Supply Chain',
'New Chip Architecture Doubles Computing Power While Halving Energy Use',
'Virtual Reality Breakthrough: Neural Interface Allows Direct Brain Connection',
];

function getHeadlinesRemaining() {
const headlinesRemaining = document.getElementById('headlines-remaining');
headlinesRemaining.innerText = `Headlines remaining: ${headlines.length}`;
}

getHeadlinesRemaining();

const channel = client.channels.get('cut-nil-tie');

channel.subscribe((message) => {
const messagesDiv = document.getElementById('headlines');
const newMessage = document.createElement('div');
const newFlag = document.createElement('span');

newFlag.className = 'bg-green-500 text-white text-xs px-2 py-1 rounded-full font-bold mr-2';
newFlag.textContent = 'NEW';

newMessage.className = 'p-3 bg-gray-50 rounded-lg flex items-center gap-2';
newMessage.appendChild(newFlag);
const messageText = document.createElement('span');
messageText.innerText = message.data;
newMessage.appendChild(messageText);
messagesDiv.prepend(newMessage);

setTimeout(() => {
newFlag.remove();
}, 5000);
});

const publishButton = document.querySelector('button') as HTMLButtonElement;

publishButton.addEventListener('click', () => {
const randomIndex = Math.floor(Math.random() * headlines.length);
const selectedHeadline = headlines[randomIndex];
headlines = headlines.filter((_, index) => index !== randomIndex);
channel.publish('headline', selectedHeadline);

getHeadlinesRemaining();

if (headlines.length === 0) {
publishButton.disabled = true;
publishButton.className = 'bg-gray-500 text-white px-4 py-2 rounded';
}
});
51 changes: 51 additions & 0 deletions examples/pub-sub-channel-messages/javascript/src/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

.tailwind-test {
@apply text-blue-500 font-bold;
}

.container {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
position: relative;
background-color: #f4f8fb;
height: 100vh;
}

.inner {
width: 100%;
max-width: 320px;
padding: 1rem 0.5rem;
}

/* InputCell */
.input-cell-container {
width: 100%;
display: flex;
flex-direction: column;
margin-bottom: 1rem;
}

.input-cell-container:last-child {
display: none;
}

@media (min-height: 400px) {
.input-cell-container:last-child {
display: flex;
}
}

input {
padding: 0.5rem;
width: 100%;
height: 2.5rem;
font-size: 0.875rem;
border-radius: 0.375rem;
outline: none;
transition: all 0.2s ease-in-out;
}
12 changes: 12 additions & 0 deletions examples/pub-sub-channel-messages/javascript/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./index.html",
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}

15 changes: 15 additions & 0 deletions examples/pub-sub-channel-messages/javascript/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"compilerOptions": {
"lib": ["dom", "es2015"],
"outDir": "./lib/cjs/",
"sourceMap": true,
"declaration": true,
"noImplicitAny": true,
"module": "commonjs",
"target": "es2017",
"allowJs": true,
"moduleResolution": "node"
},
"include": ["src/**/*.ts*"],
"exclude": ["node_modules", "dist", "lib"]
}
8 changes: 8 additions & 0 deletions examples/pub-sub-channel-messages/javascript/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
interface ImportMetaEnv {
readonly VITE_PUBLIC_ABLY_KEY: string;
// Add other environment variables here if needed
}

interface ImportMeta {
readonly env: ImportMetaEnv;
}
12 changes: 12 additions & 0 deletions examples/pub-sub-channel-messages/javascript/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { defineConfig } from 'vite'

export default defineConfig({
css: {
postcss: {
plugins: [
require('tailwindcss'),
require('autoprefixer'),
],
}
}
})
Loading

0 comments on commit 78d1ca2

Please sign in to comment.