【问题标题】:Abp notification with SignalR and simple js client带有 SignalR 和简单 js 客户端的 Abp 通知
【发布时间】:2019-10-26 06:24:46
【问题描述】:

我正在尝试使 Abp 通知工作。在带有 asp.net core 2.2 和 signalR 1.1.0 的后端 Asp.net 样板中。

我需要解决几个任务:

1. simple js client without angular(does not work, code below)
2. It is assumed that the signalR sends messages in real time, but how can the Abp handle situations if the user is offline, or has been disconnected at the time of the sending notification? If there is no such functionality in ABP, what can I do about it?
3. Does the ABP have a mechanism to confirm receipt of a notification? Can I be sure that my message has been delivered?

客户端:安装 abp-web-resources 并获取 abp.signalr.js + abp.signalr-client.js Index.html 看起来像:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">    
    <title>Document</title>
</head>
<body>    
    <div id="inputForm">
        <p>Customer ABP client</p>
        <p>Message:</p>
        <input type="text" id="message" />
        <p>User:</p>
        <input type="text" id="user" />
        <input type="button" id="sendBtn" value="send" />       

    </div>
    <div id="chatroom"></div>
    <script   src="https://code.jquery.com/jquery-3.4.1.min.js"
              integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
              crossorigin="anonymous"></script>
    <script src="node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.signalr.js"></script>
    <script src="node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.signalr-client.js"></script>
    <script>
        let myUrl = "http://localhost:21021";               
        let hubUrl = "/chat";        
        let token = "Bearer here my token";         

        var chatHub = null;

        abp.signalr.startConnection(myUrl + hubUrl, function (connection) {
            chatHub = connection; 
            connection.on('Send', function (message, userName, connectionId, time) {            
                let userNameElem = document.createElement("b");
                userNameElem.appendChild(document.createTextNode(time +" "+userName+" ("+ connectionId +")"+ ' : '));

                let elem = document.createElement("p");
                elem.appendChild(userNameElem);
                elem.appendChild(document.createTextNode(message));

                let firstElem = document.getElementById("chatroom").firstChild;
                document.getElementById("chatroom").insertBefore(elem, firstElem);     
            }); 
        }).then(function (connection) {
            abp.log.debug('Connected to myChatHub server!');
            abp.event.trigger('myChatHub.connected');
        });

        abp.event.on('myChatHub.connected', function() { 
            chatHub.invoke('sendMessage', "Hi everybody, I'm connected to the chat!"); 
        });

        document.getElementById("sendBtn").addEventListener("click", function (e) {
            let message = document.getElementById("message").value;
            let userName = document.getElementById("user").value;           

            chatHub.invoke("Send", message, userName).catch(function (err) {
                return console.error(err.toString());
            });

            event.preventDefault();
        });
    </script>
</body>
</html>

启动.cs 在配置服务中: ...

 services.AddSignalR();            
 services.AddCors(
    options => options.AddPolicy(
                    DefaultCorsPolicyName,
                    builder => builder                         
                        .AllowAnyHeader()
                        .AllowAnyMethod()
                        .AllowAnyOrigin() 
                        .AllowCredentials()
                ));

...

在配置中:

...
 app.UseAbp(options => { options.UseAbpRequestLocalization = false; });
 app.UseWebSockets();
 app.UseCors(DefaultCorsPolicyName); 
 app.UseStaticFiles();
 app.UseAuthentication();
 app.UseAbpRequestLocalization();

 app.UseSignalR(routes => { routes.MapHub<Test2Hub>("/chat"); });

app.UseMvc();
...

同样在 AuthConfigurer 中处理令牌并添加授权标头(我不写简称)

我的中心:

namespace MyProjectName.Web.Host.MyHubs
{
    [Authorize]
    public class Test2Hub : AbpHubBase, ISingletonDependency //with trancient  
                                        //not working at all: Clients == null
    {
        private IAbpSession AbpSession { get; set; }        

        public Test2Hub( )            
        {
            AbpSession = NullAbpSession.Instance;            
        }

        public async Task Send(string msg, string userName)
        {
            await this.Clients.All.SendAsync("Send", msg, userName, Context.ConnectionId, "[" + Clock.Now + "]");
        }

        public async Task SendToUser(string msg, long userId)
        {
            if (this.Clients != null)
            {
                await Clients.User(userId.ToString()).SendAsync("Send", msg, "From Server by userID ",   Context.ConnectionId, Clock.Now);
            }
            else
            {
                throw new UserFriendlyException("smthng wrong");                
            }           
        }

        public async Task<HttpContext> GetContext()
        {
            return Context.GetHttpContext();
        }

        public override async Task OnConnectedAsync()
        {            
            await Clients.All.SendAsync("Send", $"{Context.UserIdentifier} enter into chat");
            await base.OnConnectedAsync();
        }

        public override async Task OnDisconnectedAsync(Exception exception)
        {            
            await Clients.All.SendAsync("Send", $"{Context.UserIdentifier} gone...");
            await base.OnDisconnectedAsync(exception);
        }        
    }
}

控制器:

 [Route("api/[controller]/[action]")]
    public class NotificationWebController : MyProjectControllerBase, IRealTimeNotifier
    {        
        private readonly Test2Hub _testHub;       
        private readonly INotificationPublisher _notificationPublisher;
        private readonly INotificationSubscriptionManager _notificationSubscriptionManager;
        private readonly IUserNotificationManager _notificationManager;

        public NotificationWebController
        (
            IUserNotificationManager notificationManager,
            INotificationPublisher notificationPublisher,
            INotificationSubscriptionManager notificationSubscriptionManager,
            Test2Hub testHub            
        )
        {
            _testHub = testHub;
            _notificationPublisher = notificationPublisher;
            _notificationSubscriptionManager = notificationSubscriptionManager;
            _notificationManager = notificationManager;
        }

        [HttpPost]
        public async Task SendToUserBySignalR(string msg, long userId)
        {                           
            await _testHub.SendToUser(msg, userId);            
        }

        [HttpGet]
        public async Task<HttpContext> GetContext()
        {            
            return await _testHub.GetContext();            
        }

         /*
            I also tried to use the Abp notification system,
 records in the database were created, but I could not transfer it to the client
        */        

        [HttpPost]
        public async Task Subscribe(int? tenantId, long userId)
        {
            await _notificationSubscriptionManager.SubscribeAsync(new UserIdentifier(tenantId, userId), "App.SimpleMessage");
        }

        [HttpPost]
        public async Task<ActionResult> TestNotificationAbp(string message, long userId)
        {    
            var identifier = new UserIdentifier(1, userId); //tenantId = 1
            await _notificationPublisher.PublishAsync(
                "App.SimpleMessage",
                new MessageNotificationData(message),
                severity: NotificationSeverity.Info,
                userIds: new[] { identifier }
            );

            return Content("Sent notification: " + message);
        }  

        [HttpPost]
        public async Task SendNotificationsAsync(UserNotification[] userNotifications)
        {
            //realization IRealTimeNotifier, but it is not clear how to use it...
           throw new NotImplementedException();
        }                
    }

客户端不工作。错误:

abp.signalr-client.js:5 Uncaught ReferenceError: signalR is not defined
    at abp.signalr-client.js:5
    at abp.signalr-client.js:109
(anonymous) @ abp.signalr-client.js:5
(anonymous) @ abp.signalr-client.js:109
(index):38 Uncaught TypeError: Cannot read property 'startConnection' of undefined 

我做错了什么?我也希望能回答上述问题。对不起我的英语。

【问题讨论】:

标签: javascript aspnetboilerplate asp.net-core-2.2 asp.net-core-signalr


【解决方案1】:
<script src="node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.signalr.js"></script>
<script src="node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.signalr-client.js"></script>

ASP.NET 核心

使用 abp.signalr-client.js,依赖于 signalr.js。

<script src="node_modules/signalr/dist/browser/signalr.js"></script>
<script src="node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.signalr-client.js"></script>

参考资料:

ASP.NET MVC 5

使用 abp.signalr.js,这取决于信号器/集线器。

<script src="signalr/hubs"></script>
<script src="node_modules/abp-web-resources/Abp/Framework/scripts/libs/abp.signalr-client.js"></script>

参考资料:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-14
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多