Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions sdk/webpubsub-chat-client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules
dist
types
tsconfig.tsbuildinfo
.env
.yarn
*.tgz
7 changes: 7 additions & 0 deletions sdk/webpubsub-chat-client/.yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
nodeLinker: node-modules

# Temporary: Use MyGet feed for @azure scoped packages during preview.
# This will be removed once the package is published to npm.
npmScopes:
azure:
npmRegistryServer: "https://www.myget.org/F/azure-signalr-dev/npm/"
121 changes: 121 additions & 0 deletions sdk/webpubsub-chat-client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Azure Web PubSub Chat Client SDK

A client SDK for building chat applications with Azure Web PubSub.

> ⚠️ **Internal Preview**: This package is currently for internal use only and is not ready for production.

## Installation

```bash
npm install @azure/web-pubsub-chat-client
```

## Quick Start

For a complete example, see [examples/quickstart](./examples/quickstart).

```javascript
import { ChatClient } from '@azure/web-pubsub-chat-client';

// Get client access URL from your server
const url = await fetch('/negotiate?userId=alice').then(r => r.json()).then(d => d.url);

// Option 1: Login with an existing WebPubSubClient
const wpsClient = new WebPubSubClient(url);
const client = await ChatClient.login(wpsClient);

// Option 2: Login directly with URL
// const client = await new ChatClient(url).login();

console.log(`Logged in as: ${client.userId}`);

// Listen for events
client.addListenerForNewMessage((notification) => {
const msg = notification.message;
console.log(`${msg.createdBy}: ${msg.content.text}`);
});

client.addListenerForNewRoom((room) => {
console.log(`Joined room: ${room.title}`);
});

// Create a room and send messages
const room = await client.createRoom('My Room', ['bob']);
await client.sendToRoom(room.roomId, 'Hello!');

// Get message history
const history = await client.listRoomMessage(room.roomId, null, null);

// Manage room members
await client.addUserToRoom(room.roomId, 'charlie');
await client.removeUserFromRoom(room.roomId, 'charlie');

// Cleanup
client.stop();
```

## API

### ChatClient

#### Constructor

```typescript
// With existing WebPubSubClient
new ChatClient(wpsClient: WebPubSubClient)

// With client access URL
new ChatClient(clientAccessUrl: string, options?: WebPubSubClientOptions)

// With credential
new ChatClient(credential: WebPubSubClientCredential, options?: WebPubSubClientOptions)
```

#### Static Methods

| Method | Description |
|--------|-------------|
| `ChatClient.login(wpsClient)` | Create and login using an existing WebPubSubClient |

#### Properties

| Property | Type | Description |
|----------|------|-------------|
| `userId` | `string` | Current user's ID (throws if not logged in) |
| `rooms` | `RoomInfo[]` | List of joined rooms |
| `connection` | `WebPubSubClient` | Underlying WebPubSub connection |

#### Methods

| Method | Description |
|--------|-------------|
| `login()` | Connect and authenticate, returns `ChatClient` |
| `stop()` | Disconnect |
| `createRoom(title, members, roomId?)` | Create a new room with initial members |
| `getRoom(roomId, withMembers)` | Get room info |
| `addUserToRoom(roomId, userId)` | Add user to room (admin operation) |
| `removeUserFromRoom(roomId, userId)` | Remove user from room (admin operation) |
| `sendToRoom(roomId, message)` | Send text message to room, returns message ID |
| `listRoomMessage(roomId, startId, endId, maxCount?)` | Get room message history |
| `getUserInfo(userId)` | Get user profile |

#### Event Listeners

| Method | Callback Parameter | Description |
|--------|-------------------|-------------|
| `addListenerForNewMessage(callback)` | `NewMessageNotificationBody` | New message received |
| `addListenerForNewRoom(callback)` | `RoomInfo` | Joined a new room |
| `addListenerForMemberJoined(callback)` | `MemberJoinedNotificationBody` | Member joined a room |
| `addListenerForMemberLeft(callback)` | `MemberLeftNotificationBody` | Member left a room |
| `addListenerForRoomLeft(callback)` | `RoomLeftNotificationBody` | Self left a room |
| `onConnected(callback)` | `OnConnectedArgs` | Connection established |
| `onDisconnected(callback)` | `OnDisconnectedArgs` | Connection lost |
| `onStopped(callback)` | `OnStoppedArgs` | Connection stopped |

## Examples

See the [examples](./examples) directory for complete working examples.

## License

MIT
5 changes: 5 additions & 0 deletions sdk/webpubsub-chat-client/examples/battleship/.yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
nodeLinker: node-modules

npmScopes:
azure:
npmRegistryServer: "https://www.myget.org/F/azure-signalr-dev/npm/"
37 changes: 37 additions & 0 deletions sdk/webpubsub-chat-client/examples/battleship/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Battleship

Multiplayer real-time naval combat. Each player gets a grid with randomly placed ships. Attack any opponent's grid — hits and misses appear instantly for all players. Last fleet standing wins.

## How it works

| Feature | Chat SDK API |
|---|---|
| Login | `new ChatClient(url)` + `login()` |
| Create game & invite players | `createRoom(title, playerList)` |
| Join game via invitation | `addListenerForNewRoom` |
| Deploy fleet / Fire at opponent | `sendToRoom(roomId, json)` |
| Real-time attack updates | `addListenerForNewMessage` |
| Restore game state on rejoin | `listRoomMessage` |
| See who joined | `addListenerForMemberJoined` |

## Prerequisites

1. An Azure Web PubSub resource
2. Node.js 18+

## Run

```bash
cd examples/battleship
yarn install
node server.js "<your-connection-string>"
```

Open **multiple browser tabs** at `http://localhost:3000`, login as different users, and start a game.

## How to Play

- Ships are placed **randomly** when you join a game
- **Free-for-all**: no turns — click any cell on an opponent's board to attack
- A player is **eliminated** when all their ship cells are hit
- Last player alive **wins**
16 changes: 16 additions & 0 deletions sdk/webpubsub-chat-client/examples/battleship/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "battleship-example",
"version": "1.0.0",
"description": "Real-time multiplayer battleship using Web PubSub Chat SDK",
"type": "module",
"scripts": {
"start": "node server.js"
},
"author": "Microsoft",
"license": "MIT",
"dependencies": {
"@azure/web-pubsub": "^1.2.0",
"@azure/web-pubsub-chat-client": "1.0.0-beta.1",
"express": "^5.2.1"
}
}
Loading
Loading