question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Question] [Serverless] How can I send a message to an individual client using REST API?

See original GitHub issue

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:

POST /api/v1-preview/hub/chat/user/61Ztvpa0KEQeKkJBgB2ZPQ HTTP/1.1
Host: accendis-wefinance.service.signalr.net:5002
Content-Type: application/json
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE1MzEzMTgyMTUsImV4cCI6MTU2Mjg1OTQ5NCwiYXVkIjoiaHR0cHM6Ly9hY2NlbmRpcy13ZWZpbmFuY2Uuc2VydmljZS5zaWduYWxyLm5ldDo1MDAyL2FwaS92MS1wcmV2aWV3L2h1Yi9jaGF0L3VzZXIvNjFadHZwYTBLRVFlS2tKQmdCMlpQUSIsInN1YiI6IiJ9.aVhw0AyQ-WuT9NIymFzESn6Gv3R3zLedddqCngLzxFg
Cache-Control: no-cache
Postman-Token: 329b9cbd-8f86-4e62-8a3f-c5e23b8af025

{ "target": "newMessage0", "arguments": [ {
	"sender": "mario",
	"text": "API rest do SignalR"
} ] }

And as result, I receive a 202 but nothing happens on client side.

How can I see what really happened?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
mariomeyrellescommented, Jul 13, 2018

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!

1reaction
shiweiwei114commented, Nov 11, 2020

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

REST API (API Gateway v1) - Serverless Framework
This guide documents using API Gateway v1 REST API via the http event. ... in your lambda function AWS will send an error...
Read more >
How to Setup a Basic Serverless REST API with AWS Lambda ...
Let's Configure Stuff on AWS xD​​ We are going to create a REST endpoint that accepts a POST request with some text as...
Read more >
AWS Serverless Messaging - API Gateway to SNS walk thru
Bart discusses some of the powerful serverless messaging tools of AWS - the API Gateway, Simple Notification Service (SNS), and the Simple ...
Read more >
Managing backend requests and frontend notifications ... - AWS
In this example, the API request can only inform callers about drivers at the end of the lengthy process request. The asynchronous model....
Read more >
Make a request to an external API - Twilio
You can create a Function using the Twilio Console or the Serverless Toolkit ... to send a text message to the user that...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found