简体   繁体   English

如何在 ASP.net 核心 web 应用程序中实现 signalR 中的组

[英]how to implement groups in signalR in ASP.net core web application

I am using signalR groups for, whenever a user changed a data then every user in the group can see the changed data in the real time.我正在使用 signalR 组,每当用户更改数据时,组中的每个用户都可以实时看到更改的数据。

I have used ASP.net core web application tempelate for this project.我已经为这个项目使用了 ASP.net 核心 web 应用程序模板。

the code for the controller is: controller 的代码是:

public class PatientCollectionsController : ControllerBase
{
    private readonly IHubContext<GroupHub> groupHub;

    public PatientCollectionsController(Func<string, IPatientCollectionsService> serviceResolver, IConfiguration configuration, ILogger<PatientCollectionsModel> logger,
        IHubContext<GroupHub> grpHub)
    {
        this.dbservice = serviceResolver(configuration.GetValue<string>("CollectionsDbChoice").ToLower());
        this.logger = logger;
        this.groupHub = grpHub;
    }

    // GET: api/<PatientCollectionsController>
    [HttpGet]
    public IActionResult Get()
    {
        HttpContext.VerifyUserHasAnyAcceptedScope(scopeRequiredByApi);

        try
        {
            return Ok(dbservice.GetPatientCollections());
        }
        catch (Exception ex)
        {
            logger.LogError("failed to get Patient Collections", ex.Message, ex.StackTrace);
            logger.LogInformation(ex.Message, ex.StackTrace);
            return StatusCode(500, "Internal server error");
        }
    }
    
    // PUT api/<PatientCollectionsController>/5
    [HttpPut("{id}")]
    public void Put(string id, [FromBody] PatientCollectionsModel value)
    {
        try
        { 
            dbservice.PutPatientCollection(value);
        }
        catch(Exception ex)
        {
            logger.LogError("failed to put Patient Collections", ex.Message, ex.StackTrace);
            logger.LogInformation(ex.Message, ex.StackTrace);
            StatusCode(500, "Internal server error");
        }
    }


    static readonly string[] scopeRequiredByApi = new string[] { "access_as_signedin_user" };
    private IPatientCollectionsService dbservice;
    private ILogger<PatientCollectionsModel> logger;
}

the code for the service is:该服务的代码是:

public class PatientCollectionsDBService : IPatientCollectionsService
{
    #region ctor
    public PatientCollectionsDBService(IDatabaseSettings settings)
    {
        CloudStorageAccount storageAccount = CloudStorageAccount.Parse(settings.ConnectionString);
        CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
        patientCollectionsTable = tableClient.GetTableReference("PatientCollections");
        patientCollectionsTable.CreateIfNotExists();
    }
    #endregion

    #region IPatientCollectionsService Impl
    public List<PatientCollectionsModel> GetPatientCollections()
    {
        TableContinuationToken token = null;
        var pc = new List<PatientCollectionsModel>();
        do
        {
            var tableQuery = new TableQuery<DynamicTableEntity>
            {
                FilterString = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, "current")
            };
            var queryResult = patientCollectionsTable.ExecuteQuerySegmented(tableQuery, token);
            foreach (var entity in queryResult)
            {
                pc.Add(new PatientCollectionsModel
                {
                    Id = entity.RowKey,
                    FirstName = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.FirstName)]),
                    PtId = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.PtId)]),
                    DOS = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.DOS)]),
                    PatientBalance = (float)entity.Properties[nameof(PatientCollectionsModel.PatientBalance)].DoubleValue,
                    EOB = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.EOB)]),
                    PhoneNo = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.PhoneNo)]),
                    BalanceCurrent = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.BalanceCurrent)]),
                    BalanceThirtyPlus = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.BalanceThirtyPlus)]),
                    BalanceThirtyPlusCall = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.BalanceThirtyPlusCall)]),
                    BalanceSixtyPlus = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.BalanceSixtyPlus)]),
                    BalanceSixtyPlusCall = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.BalanceSixtyPlusCall)]),
                    Notes = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.Notes)]),
                    BalanceNinetyPlus = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.BalanceNinetyPlus)]),
                    CollectionOneTwentyPlus = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.CollectionOneTwentyPlus)]),
                    CollectionOneTwentyPlusCall = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.CollectionOneTwentyPlusCall)]),
                    Notes2 = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.Notes2)]),
                    Notes3 = Convert.ToString(entity.Properties[nameof(PatientCollectionsModel.Notes3)])
                });
            }

        } while (token != null);

        return pc;
    }

    public async Task<bool> PutPatientCollection(PatientCollectionsModel pc)
    {
        DynamicTableEntity newOne = new DynamicTableEntity { PartitionKey = "current", RowKey = pc.PtId };
        Dictionary<string, EntityProperty> props = new Dictionary<string, EntityProperty>()
        {
            {nameof(PatientCollectionsModel.FirstName), new EntityProperty(pc.FirstName) },
            {nameof(PatientCollectionsModel.PtId), new EntityProperty(pc.PtId) },
            {nameof(PatientCollectionsModel.PatientBalance), new EntityProperty(pc.PatientBalance) },
            {nameof(PatientCollectionsModel.EOB), new EntityProperty(pc.EOB) },
            {nameof(PatientCollectionsModel.PhoneNo), new EntityProperty(pc.PhoneNo) },
            {nameof(PatientCollectionsModel.BalanceCurrent), new EntityProperty(pc.BalanceCurrent) },
            {nameof(PatientCollectionsModel.BalanceThirtyPlus), new EntityProperty(pc.BalanceThirtyPlus) },
            {nameof(PatientCollectionsModel.BalanceThirtyPlusCall), new EntityProperty(pc.BalanceThirtyPlusCall) },
            {nameof(PatientCollectionsModel.DOS), new EntityProperty(pc.DOS) },
            {nameof(PatientCollectionsModel.BalanceSixtyPlus), new EntityProperty(pc.BalanceSixtyPlus) },
            {nameof(PatientCollectionsModel.BalanceSixtyPlusCall), new EntityProperty(pc.BalanceSixtyPlusCall) },
            {nameof(PatientCollectionsModel.Notes), new EntityProperty(pc.Notes) },
            {nameof(PatientCollectionsModel.BalanceNinetyPlus), new EntityProperty(pc.BalanceNinetyPlus) },
            {nameof(PatientCollectionsModel.CollectionOneTwentyPlus), new EntityProperty(pc.CollectionOneTwentyPlus) },
            {nameof(PatientCollectionsModel.CollectionOneTwentyPlusCall), new EntityProperty(pc.CollectionOneTwentyPlusCall) },
            {nameof(PatientCollectionsModel.Notes2), new EntityProperty(pc.Notes2) },
            {nameof(PatientCollectionsModel.Notes3), new EntityProperty(pc.Notes3) }
        };
        newOne.Properties = props;
        newOne.ETag = "*";

        TableOperation updateDenial = TableOperation.Replace(newOne);
        var tableResult = await patientCollectionsTable.ExecuteAsync(updateDenial);

        return tableResult.HttpStatusCode == (int)HttpStatusCode.OK
            || tableResult.HttpStatusCode == (int)HttpStatusCode.NoContent;
    }

then i created a hub:然后我创建了一个集线器:

[Authorize]
public class GroupHub : Hub
{
    public async Task JoinGroup(string group)
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, group);
        await Clients.Group(group).SendAsync("Send", $"{Context.ConnectionId} has joined the group {group}.");
    }

    public async Task LeaveGroup(string group)
    {
        await Groups.RemoveFromGroupAsync(Context.ConnectionId, group);
    }

}

Can anyone suggest me what should i do to make it work and also how can i send a users to different groups.谁能建议我应该怎么做才能使它工作,以及如何将用户发送到不同的组。

await Groups.AddToGroupAsync(Context.ConnectionId, group); await Groups.RemoveFromGroupAsync(Context.ConnectionId, group);

As we all known, the connections are added to or removed from groups via the AddToGroupAsync and RemoveFromGroupAsync methods.众所周知,连接是通过AddToGroupAsyncRemoveFromGroupAsync方法添加到组或从组中删除的。 So, to manage (add/remove) Users in the groups, first you should get the User's ConnectionID .因此,要管理(添加/删除)组中的用户,首先您应该获取用户的ConnectionID

In the Hub's OnConnectedAsync method, you could get the ConnectionID via the Context.在 Hub 的OnConnectedAsync方法中,您可以通过 Context 获取 ConnectionID。 Then, store the ConnectionID and UserName into the database.然后,将ConnectionIDUserName存储到数据库中。

In the Hub's OnDisconnectedAsync method, if user disconnected, remove the user from the table.在 Hub 的 OnDisconnectedAsync 方法中,如果用户断开连接,则将用户从表中删除。

After that, you could according the UserName to find the ConnectionID and use the AddToGroupAsync and RemoveFromGroupAsync methods to add/remove user to the group.之后,您可以根据UserName找到ConnectionID并使用AddToGroupAsyncRemoveFromGroupAsync方法将用户添加/删除到组。

//require using Microsoft.AspNetCore.SignalR;
//require using Microsoft.AspNetCore.Authorization;
[Authorize]
public class ChatHub : Hub
{ 
    private readonly ApplicationDbContext _context; //DB context

    public ChatHub(ApplicationDbContext context)
    {
        _context = context;
    }
    public override Task OnConnectedAsync()
    { 
        //get Logged user name.
        var IdentityName = Context.User.Identity.Name;

        SignalRUser user = new SignalRUser() { ConnectionID = Context.ConnectionId, UserName = IdentityName };
        _context.SignalRUser.Add(user);
        _context.SaveChanges();

        return base.OnConnectedAsync();
    } 
    public override async Task OnDisconnectedAsync(Exception exception)
    {
        var IdentityName = Context.User.Identity.Name; 
        var user =  _context.SignalRUser.Where(c => c.UserName == IdentityName).FirstOrDefault();
        //remove user if user disconnected
        if(user != null)
        {
            _context.SignalRUser.Remove(user);
            _context.SaveChanges();
        }

        await base.OnDisconnectedAsync(exception);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在ASP.NET Web API Core应用程序上使用QUARTZ实现调度程序? - How to implement a scheduler using QUARTZ on an ASP.NET Web API Core application? ASP.NET中如何实现搜索过滤 Core Web API - How to implement search filter in ASP.NET Core Web API 我如何使用C#在ASP.NET Web API(非.NET Core)中实现API网关 - how can i implement api gateway in asp.net web api (not .net core) using c# 如何使用signalR转换ASP.Net Web API的日期格式? - how to convert date format for ASP.Net Web API with signalR? 在 ASP.NET Core 5.0 Web API 中实现 DelegatingHandler? - Implement DelegatingHandler in ASP.NET Core 5.0 Web API? 在 ASP.NET Core Web API 中实现 HTTP 缓存(ETag) - Implement HTTP Cache (ETag) in ASP.NET Core Web API 处理身份验证/授权:ASP.NET Core Web 应用程序 =&gt; ASP.NET Core Web API =&gt; SQL - Handling authentication/authorization: ASP.NET Core Web Application => ASP.NET Core Web API => SQL ASP.NET Core 1.1 Web API在Web应用程序上不起作用 - ASP.NET Core 1.1 Web API not working on Web Application Asp.NET Web API和SignalR Cors - Asp.NET Web API and SignalR Cors ASP.NET Core Web API - 如何使用 Fluent Validation 实现可选验证 - ASP.NET Core Web API - How to implement optional validation using Fluent Validation
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM