Azure Web PubSub - Javascript - Groups
- Dominant language
- TypeScript
- Stars
- 147
- Forks
- 96
- Avg merge
- 19h 28m
- Merged PRs (30d)
- 87
Description
### Describe the bug
The chat demo is nice and super basic demo to get started but in real world a users need to be able connect to a specific group and/or multiple specific groups and send messages to only that group. I am trying to figure out how to properly implement this groups using **WebPubSubServiceClient** and **WebPubSubEventHandler**. I have spent hours looking through the Azure documentation and examples on this repo to try and figure out how to dynamically join a Group, send messages to a specific group only.
In the docs - In a hub, you can have multiple groups and one client can subscribe to multiple groups at the same time.
When using subprotocol, you can only publish to a group instead of broadcasting to the whole hub.
I can not find examples of the above. All I can find when looking through the code is serviceClient.sendToAll()
Example doing something similar with Redis PubSub or Uwebsockets - when the websocket is opened you can do something like `socket.subscribe(`${socket.client.roomName}') `and then you could just publish data to that client room name publish(`${socket.client.roomName}', jsonData) `.
### Requirements
A user be able to connect to new groups with dynamic names - IE. friendsGroup, familyGroup, workGroup and be able to send messages to the specific groups.
Also have an API server that I want to be able send JSON data to my below server and depending on the JSON data be able to send the data to the correct group
### To Reproduce
#### Client
```
let id = prompt('Please input your user name');
let res = await fetch(`/negotiate?id=${id}`);
let data = await res.json();
let ws = new WebSocket(data.url, 'json.webpubsub.azure.v1');
ws.onopen = () => {
console.log('connected');
// ws.send(JSON.stringify({
// "type": 'joinGroup',
// "group": 'chat'
// }));
}
ws.onerror = (event) => {
console.error("WebSocket error observed:", event);
};
ws.onclose = (event) => {
console.log("WebSocket is closed now.");
};
```
# Server
```
const result = require('dotenv').config();
const express = require('express');
const { WebPubSubServiceClient } = require('@azure/web-pubsub');
const { WebPubSubEventHandler } = require('@azure/web-pubsub-express');
const app = express();
const hubName = 'chat';
let port = process.env.PORT || 8080; // set our port
let serviceClient = new WebPubSubServiceClient(process.env.AZURE_WEB_PUBSUB_CONNECTION, hubName);
app.get('/negotiate', async (req, res) =>
{
let id = req.query.id;
let token = await serviceClient.getAuthenticationToken({
userId: id,
roles: ['webpubsub.sendToGroup.chat', 'webpubsub.joinLeaveGroup.chat']
});
res.send({
url: token.url
});
});
let handler = new WebPubSubEventHandler(hubName, ['*'], {
path: '/eventhandler',
onConnected: async req => {
console.log(`Connected`, req.context );
console.log(`${req.context.userId} connected`);
},
handleUserEvent: async (req, res) =>
{
if (req.context.eventName === 'message')
{
await serviceClient.sendToAll({ "eventName": req.context.eventName, "userID": req.context.userId, "data": req.data}, { contentType: 'application/json' });
}
res.success();
}
});
app.use(handler.getMiddleware());
app.use(express.static('public'));
app.listen(port, () => {
console.log(`Listening on port ${ port } `);
console.log(`Azure WebPubSub Upstream ready at http://localhost:3000${handler.path}`)
});
```
### Further technical details
"@azure/web-pubsub": "^1.0.0-beta.3",
"@azure/web-pubsub-express": "^1.0.0-beta.3",
"dotenv": "^10.0.0",
"express": "^4.17.1"
### Additional Comments
I hope the above makes sense. Please let me know if I am missing something or if you need more information.
Thank You
Sean
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the WebPubSubServiceClient and WebPubSubEventHandler usage shown in the client and server snippets, then compare it with the Azure documentation and repository examples mentioned in the issue. Document a complete flow for dynamically joining multiple groups and sending JSON only to the selected group, including the client and API-server paths. Done means a newcomer can follow the example without relying on sendToAll().
Written by the indexing model from the issue text.
Assessment
- Tech stack
- azure, javascript
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100