Azure / azure-functions-signalrservice-extension

Azure Functions bindings for SignalR Service. Project moved to https://github.com/Azure/azure-sdk-for-net/tree/main/sdk/signalr/Microsoft.Azure.WebJobs.Extensions.SignalRService .
97 stars 48 forks source link

Send message to group is not working properly. #89

Open Tharindu-Diluksha opened 4 years ago

Tharindu-Diluksha commented 4 years ago

Sending messages to group using "SignalRMessage" is sending messages to many groups.

Users are added to multiple groups. `

                [FunctionName("AddUserToGroup")]public async Task<IActionResult> AddUserToGroup(
                [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "addToGroup")]HttpRequest req,
                [SignalR(HubName = "x")] IAsyncCollector<SignalRGroupAction> 
                signalRGroupActions, ILogger log)
                  {
                string userId = req.Query["userId"];

                var user = await _userService.GetUserAsync(userId);

                List<Task> groupTaskList = new List<Task>();

                foreach (var customerRole in user.CustomerRoles.Where(c => c.Customer != "*"))
                {
                    groupTaskList.Add(signalRGroupActions.AddAsync(
                    new SignalRGroupAction
                    {
                        UserId = userId,
                        GroupName = customerRole.CustomerId,
                        Action = GroupAction.Add
                    }));
                }

                await Task.WhenAll(groupTaskList);

                return new OkObjectResult("Added to group(s)");
              } 

`

Then messages are sent to a specific group `

       [FunctionName("SendMessageToGroup")]public Task SendMessageToGroup(
       [ServiceBusTrigger("%NotifySignalRClientGroupQueueName%", Connection = "AzureSBConnection")]Message message,
       [SignalR(HubName = "x")]IAsyncCollector<SignalRMessage> signalRMessages)
       {
        dynamic signalRMessage = new ExpandoObject();
        var targetFunctionName = string.Empty;

        var customerId = message.UserProperties.ContainsKey(ServiceBusMessageProperties.CustomerId) ?
            message.UserProperties[ServiceBusMessageProperties.CustomerId].ToString() : "*";
        var messageType = message.UserProperties[ServiceBusMessageProperties.MessageType].ToString();

        if (messageType == ServiceBusMessageTypes.AlarmStatusUpdate)
        {
            var activeAlarmStatus = JsonConvert.DeserializeObject<ActiveAlarmStatusDto>(Encoding.UTF8.GetString(message.Body));
            targetFunctionName = "updateAlarmStatus";
            signalRMessage = activeAlarmStatus;
        }

        return signalRMessages.AddAsync(
            new SignalRMessage
            {
                GroupName = customerId,
                Target = targetFunctionName,
                Arguments = new[] { signalRMessage }
            });
    }

` Expected outcome :- Messages will be received only the users in the specific group

Actual outcome :- Messages are received by users in different groups

JialinXin commented 4 years ago

@Tharindu-Diluksha, would you add some logs to validate the groups for new user to add and real group when you send messages? Or you can refer to the Customer Log for a further check on service side logs that the request is as expected. We're sure to cover the your scenario that a user in multiple groups, only target group users could receive message. Let me know if you have any problem, we can help take a further look.

JialinXin commented 4 years ago

@Tharindu-Diluksha any update? Is the issue still happening?

Tharindu-Diluksha commented 4 years ago

@JialinXin Sorry for the delay. We have parked that implementation for the time being. I'll get back to you soon. Btw is there a way to find the clients in groups in SignalR service other than using logs?

JialinXin commented 4 years ago

@Tharindu-Diluksha We have an API to Check user existence in a group but don't provide API to get connection list in a group.

Tharindu-Diluksha commented 4 years ago

@JialinXin I have used both logs and REST API to investigate the issue. In the logs, I don't see anything related to group assignments. Also, for the Rest API call, I'm always getting an empty response. REST APIs Check User Existence Always Returns Empty Body #793 (I think this is correct since I'm getting 200 as status. So my user is in the group)

Here is the log.

`{ "properties": {"message":"Entered Serverless mode.","type":"ConnectivityLogs","collection":"Connection","connectionId":"dIShnQVGtyOe7zSMgGXSOQ0632d5c81","userId":"f0e9af4f-5f22-4fae-b488-ca14ebb34a22","transportType":"WebSockets","connectionType":"Client"}, "operationName": "ServerlessModeEntered", "category": "AllLogs", "level": "Informational", "callerIpAddress": "124.43.17.93", "resourceId": "/SUBSCRIPTIONS/39EB01C9-7FF3-40F8-8995-6F7205C27D96/RESOURCEGROUPS/CLOUDKEYSECURERESOURCEGROUP/PROVIDERS/MICROSOFT.SIGNALRSERVICE/SIGNALR/TYTONDEVSIGNALR", "time": "2020-01-22T05:01:07Z", "location": "australiaeast"}

{ "properties": {"message":"Handshake completed. Protocol:json, Version:1","type":"ConnectivityLogs","collection":"Connection","connectionId":"dIShnQVGtyOe7zSMgGXSOQ0632d5c81","userId":"f0e9af4f-5f22-4fae-b488-ca14ebb34a22","transportType":"WebSockets","connectionType":"Client"}, "operationName": "HandshakeCompleted", "category": "AllLogs", "level": "Informational", "callerIpAddress": "124.43.17.93", "resourceId": "/SUBSCRIPTIONS/39EB01C9-7FF3-40F8-8995-6F7205C27D96/RESOURCEGROUPS/CLOUDKEYSECURERESOURCEGROUP/PROVIDERS/MICROSOFT.SIGNALRSERVICE/SIGNALR/TYTONDEVSIGNALR", "time": "2020-01-22T05:01:07Z", "location": "australiaeast"}

{ "properties": {"message":"Connection started","type":"ConnectivityLogs","collection":"Connection","connectionId":"dIShnQVGtyOe7zSMgGXSOQ0632d5c81","userId":"f0e9af4f-5f22-4fae-b488-ca14ebb34a22","transportType":"WebSockets","connectionType":"Client"}, "operationName": "ConnectionStarted", "category": "AllLogs", "level": "Informational", "callerIpAddress": "124.43.17.93", "resourceId": "/SUBSCRIPTIONS/39EB01C9-7FF3-40F8-8995-6F7205C27D96/RESOURCEGROUPS/CLOUDKEYSECURERESOURCEGROUP/PROVIDERS/MICROSOFT.SIGNALRSERVICE/SIGNALR/TYTONDEVSIGNALR", "time": "2020-01-22T05:01:07Z", "location": "australiaeast"}

{ "properties": {"message":"Connection ended.","type":"ConnectivityLogs","collection":"Connection","connectionId":"dIShnQVGtyOe7zSMgGXSOQ0632d5c81","userId":"f0e9af4f-5f22-4fae-b488-ca14ebb34a22","transportType":"WebSockets","connectionType":"Client"}, "operationName": "ConnectionEnded", "category": "AllLogs", "level": "Informational", "callerIpAddress": "124.43.17.93", "resourceId": "/SUBSCRIPTIONS/39EB01C9-7FF3-40F8-8995-6F7205C27D96/RESOURCEGROUPS/CLOUDKEYSECURERESOURCEGROUP/PROVIDERS/MICROSOFT.SIGNALRSERVICE/SIGNALR/TYTONDEVSIGNALR", "time": "2020-01-22T05:12:23Z", "location": "australiaeast"}`

JialinXin commented 4 years ago

@Tharindu-Diluksha. Thanks for providing the traces.

May I understand your issue is user UA is added to groups GA, GB, GC, GD for example. Then UA send a message to GA, but GB, GC, GD also received?

I checked the traces for your resource and before connectionId = dIShnQVGtyOe7zSMgGXSOQ0632d5c8, there're 20+ group messages to about 10 groups in million seconds. Is it possible that UA is sending to all the groups UA belongs to instead of single one?

tehmas commented 4 years ago

I was facing a similar problem. Following were the reasons:

  1. The user id was not unique throughout groups.
  2. Group names had "-". Swagger documentation states that names should have only alphanumeric characters or underscores.

Currently, it seems that my issue has been fixed. I will provide new findings if it isn't.

Hope this helps.

Tharindu-Diluksha commented 4 years ago

@JialinXin my problem is messages are being sent to some unexpected groups.

I have two users, UA with group GA and UB with group GB. When I send the message to the GA, the UA is receiving the message and UB also receiving the message. I'm expecting only the users in GA (UA) are receiving messages however that's not the case (UB is also receiving the message).

@tehmas thanks for your insights. We have the same user in multiple groups (so the same user is expected in different groups). We have dashes ("-") for the group names since they are just GUID's. @JialinXin can you please provide any insights on group names? @tehmas I found out that there is no such limitation now https://github.com/Azure/azure-signalr/issues/345

JialinXin commented 4 years ago

@Tharindu-Diluksha Correct about GroupName validation rules, now we only check GroupName length and NotNullOrEmpty. Since I'm not able to repro your problem in our side, would you provide some detail traces about datetime, resourceId the issue happened, email jixin[at]microsoft.com.

Besides, is this stable repro or some random issue? Is that possible that UB is previously added to GA but didn't get deleted which leads to current situation?

tehmas commented 4 years ago

@Tharindu-Diluksha Thanks for pointing out towards Azure/azure-signalr#345

The swagger documentation is not updated, I guess. https://github.com/Azure/azure-signalr/blob/dev/docs/swagger/v1.json

Strangely, my issue seems to have been resolved after I made the above mentioned two changes. The issue was occurring frequently on the free tier on different time periods.

JialinXin commented 4 years ago

Hello, just a double check if you still have the problem.

tehmas commented 4 years ago

I thought it was resolved but it still occurred again.

JialinXin commented 4 years ago

I thought it was resolved but it still occurred again.

So would you provide details about scenario and issue you meet. You may send email to jixin[at]microsoft.com about your ResourceId and timestamp the problem occurred.

tehmas commented 4 years ago

It occurs randomly. I will let you know when I see it occurring again.

Tharindu-Diluksha commented 4 years ago

I tested it again using a sample app with simple UserIds and Groups Names. But I couldn't recreate the issue. I'm going to keep this open until @tehmas response. Thank you all!

tehmas commented 4 years ago

@JialinXin I created a new project and deployed it to Azure. I can't confirm if messages were being sent to multiple groups since only one group was subscribed at that time. However, duplicate message behavior started to occur. As far as I remember, it might be occurring at that time as well. I have emailed you the details.

I will update this ticket again after reproducing exactly the same issue when multiple groups are subscribed.

JialinXin commented 4 years ago

@tehmas I've replied in the email. Please check and let me know if you have any further findings.