Closed mariomeyrelles closed 6 years ago
The id in url (61Ztvpa0KEQeKkJBgB2ZPQ) is the connection id. We don't support send message to connection id as it's not easy to get it in Azure function. Instead we support send message to a user id (/api/v1-preview/hub/chat/user
). User id is the NameIdentifier claim in access token (this is something you can control when you're generating the access token in Azure function). A sample can be found here:
Pay attention to GenerateAccessToken()
which shows how to generate a token with user id.
Thanks @chenkennt
It works!
For sake of completeness, here is an example of token generation (negotiation) Azure Function in Javascript. Claims.NameIdentifier
maps to sub
in jwt:
var jwt = require('jsonwebtoken')
module.exports = function (context, req, connectionInfo) {
var token = {
"iss": "MyService",
"aud": connectionInfo.endpoint,
"sub": req.query.uid
}
var secret = process.env["AzureSignalRKey"];
var signed = jwt.sign(token,secret, { expiresIn: '48h' });
connectionInfo.accessKey = signed;
context.res = { body: connectionInfo };
context.done();
};
On the client, the negotiation and connection process can be done like this:
function getConnectionInfo() {
return axios.post(`${apiBaseUrl}/api/SignalRInfo?uid=${data.username}`, null, getAxiosConfig())
.then(resp => resp.data);
}
getConnectionInfo().then(info => {
const options = {
accessTokenFactory: () => info.accessKey,
logMessageContent: false
};
const connection = new signalR.HubConnectionBuilder()
.withUrl(info.endpoint, options)
.configureLogging(signalR.LogLevel.Trace)
.build();
connection.on('newMessage', newMessage);
connection.onclose(() => console.log('disconnected'));
console.log('connecting...');
connection.start()
.then((data) => console.log('connected!', data))
.catch(console.error);
}).catch(console.error);
Thanks for your help again!
Good to know it works, and thanks for the complete sample! 😃
In this scenario what did you use for userId input binding on your negotiate Azure function?
In this scenario what did you use for userId input binding on your negotiate Azure function?
I don't think @mariomeyrelles is putting any userId to the input binding for SignalR service, he was generating the access token by himself and adding the userId as part of the token signature.
Dear Sirs,
I have studied the examples and I fully understand the architecture of Azure SignalR. I was able to broadcast messages from Postman. Also, I was able to run a chat example and was able to exchange messages.
The issue is: in a serverless scenario, how would I identify the id of an individual connected user? How Javascript clients can obtain their ID on Azure SignalR Service? This is needed because I want to send individual messages to a given user when his/her command gets processed on the backend. For example, in my use case, I would use a Azure Function to process a command that can take minutes to be executed.
What I have tried:
Using trace log on javascript client side, I was able to find an ID during negotiation:
Information: SSE connected to https://accendis-wefinance.service.signalr.net:5001/client/?hub=chat&id=61Ztvpa0KEQeKkJBgB2ZPQ&access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE1MzEzNTY4OTcsImV4cCI6MTUzMTM1ODY5NywiaWF0IjoxNTMxMzU2ODk3LCJhdWQiOiJodHRwczovL2FjY2VuZGlzLXdlZmluYW5jZS5zZXJ2aWNlLnNpZ25hbHIubmV0OjUwMDEvY2xpZW50Lz9odWI9Y2hhdCJ9.NBFYcQaq-pl3c31AAeKmrLBIGnw-uON_MNWY0yMvJ_Y Utils.ts:165:20
So then I tried to build a new request using the id like this:
And as result, I receive a 202 but nothing happens on client side.
How can I see what really happened?