Azure / azure-webpubsub

Azure Web PubSub Service helps you to manage WebSocket connections and do publish and subscribe in an easy way
https://azure.github.io/azure-webpubsub/
MIT License
132 stars 83 forks source link

Azure Web PubSub - Javascript - Groups #225

Open szarkowicz opened 2 years ago

szarkowicz commented 2 years ago

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

vicancy commented 2 years ago

Sorry for the late response, a quick update to the group related samples are here: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/web-pubsub/web-pubsub/test/groups.spec.ts#L22 (more to provide soon)

szarkowicz commented 2 years ago

Hi @vicancy,

Has there been any updates to the Join and Leave Group documentation?

It would be very helpful if there was specific documentation about joining groups using the Simple WebSocket client and PubSub WebSocket client. Also a breakdown of the advantages of one vs the other. Right now you have to jump through examples and try and put the pieces together. It seems like something as important as joining groups would be well documented but I can not seem to find it anywhere using the following document link - https://docs.microsoft.com/en-us/azure/azure-web-pubsub.

Can you please provide any links to documentation that have the client joining / leaving groups?

Thanks in advance