加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – 适用于多个用户的EWS通知中心

发布时间:2020-12-15 19:43:26 所属栏目:asp.Net 来源:网络整理
导读:我正在尝试创建一个服务来将交换通知推送到asp.net应用程序,最终使用SignalR. 我的计划是创建一个通知中心,在每个用户登录到asp应用程序时为其预订,并为他们监听通知.当收到通知时,项目的第二部分是使用signalR仅向每个用户发送正确的通知.一旦他们注销或超
我正在尝试创建一个服务来将交换通知推送到asp.net应用程序,最终使用SignalR.

我的计划是创建一个通知中心,在每个用户登录到asp应用程序时为其预订,并为他们监听通知.当收到通知时,项目的第二部分是使用signalR仅向每个用户发送正确的通知.一旦他们注销或超时,通知中心将取消订阅.

到目前为止,我已经完成了一些基本的测试,并且可以通过我的凭证硬编码在一个小的控制台应用程序中接收通知.我正在努力的是如何同时为多个人这样做.例如,我是否必须为每个用户创建单独的线程,还是有更好的方法?

我想无论我不得不使用模仿而不是持有每个用户的凭据吗?如果每个用户都有活动会话,我还必须找到一种自动刷新超时的方法.

下面是我发现并且一直在玩的一些代码,我将很感激任何想法或任何人可以分享我如何能够最好地实现这一目标的例子.

非常感谢

安迪

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Threading.Tasks;
using Microsoft.Exchange.WebServices.Data;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {

                ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
                service.Url = new Uri("https://server/EWS/Exchange.asmx");
                service.Credentials = new NetworkCredential("user","pass","domain");
                SetStreamingNotifications(service); 
                while (true)
                { }


        }

        static void SetStreamingNotifications(ExchangeService service)
        {
            // Subscribe to streaming notifications on the Inbox folder,and listen
            // for "NewMail","Created",and "Deleted" events.
            StreamingSubscription streamingsubscription = service.SubscribeToStreamingNotifications(
                new FolderId[] { WellKnownFolderName.Calendar,WellKnownFolderName.Inbox },EventType.Created,EventType.Modified);

            StreamingSubscriptionConnection connection = new StreamingSubscriptionConnection(service,9);

            connection.AddSubscription(streamingsubscription);
            // Delegate event handlers.
            connection.OnNotificationEvent +=
                new StreamingSubscriptionConnection.NotificationEventDelegate(OnEvent);
            connection.OnSubscriptionError +=
                new StreamingSubscriptionConnection.SubscriptionErrorDelegate(OnError);
            connection.OnDisconnect +=
                new StreamingSubscriptionConnection.SubscriptionErrorDelegate(OnDisconnect);
            connection.Open();

            Console.WriteLine("--------- StreamSubscription event -------");
        }

        static private void OnDisconnect(object sender,SubscriptionErrorEventArgs args)
        {
            // Cast the sender as a StreamingSubscriptionConnection object.          
            StreamingSubscriptionConnection connection = (StreamingSubscriptionConnection)sender;
            // Ask the user if they want to reconnect or close the subscription.
            ConsoleKeyInfo cki;
            Console.WriteLine("The connection to the subscription is disconnected.");
            Console.WriteLine("Do you want to reconnect to the subscription? Y/N");
            while (true)
            {
                cki = Console.ReadKey(true);
                {
                    if (cki.Key == ConsoleKey.Y)
                    {
                        connection.Open();
                        Console.WriteLine("Connection open.");
                        break;
                    }
                    else if (cki.Key == ConsoleKey.N)
                    {
                        // The ReadKey in the Main() consumes the E.
                        Console.WriteLine("nnPress E to exit");
                        break;
                    }
                }
            }
        }

        static void OnEvent(object sender,NotificationEventArgs args)
        {
            StreamingSubscription subscription = args.Subscription;

            // Loop through all item-related events.
            foreach (NotificationEvent notification in args.Events)
            {

                switch (notification.EventType)
                {
                    case EventType.NewMail:
                        Console.WriteLine("n-------------Mail created:-------------");
                        break;
                    case EventType.Created:
                        Console.WriteLine("n-------------Item or folder created:-------------");
                        break;
                    case EventType.Deleted:
                        Console.WriteLine("n-------------Item or folder deleted:-------------");
                        break;
                }
                // Display the notification identifier.
                if (notification is ItemEvent)
                {
                    // The NotificationEvent for an e-mail message is an ItemEvent.
                    ItemEvent itemEvent = (ItemEvent)notification;
                    Console.WriteLine("nItemId: " + itemEvent.ItemId.UniqueId);

                }
                else
                {
                    // The NotificationEvent for a folder is an FolderEvent.
                    //FolderEvent folderEvent = (FolderEvent)notification;
                    //Console.WriteLine("nFolderId: " + folderEvent.FolderId.UniqueId);
                }
            }
        }
        static void OnError(object sender,SubscriptionErrorEventArgs args)
        {
            // Handle error conditions.
            Exception e = args.Exception;
            Console.WriteLine("n-------------Error ---" + e.Message + "-------------");
        }
    }
}

解决方法

我解决这个问题的方法是:

>拥有一个有权冒充所有用户的帐户.
>我通过提供用户名和帐户为该帐户创建服务
密码.
>我冒充用户并将用户的订阅添加到
连接
>我创建了另一个服务,它是主服务的关闭
相同的用户名和密码,将冒充其他用户
然后将订阅添加到同一连接

这是我的代码的两个部分.忘记LogDevice它只是内部的东西.
第一部分是详细的模拟并将服务添加到服务列表中
在我的情况下,服务列表是一个字典,userSMTP是密钥,这里的UserSMTP密钥是模拟帐户.

/// <summary>
    /// Impersonate one user at a time and without using the autodiscovery method to find the proper url for the userSmtp,/// and copy the provided url to the usersmtp.
    /// </summary>
    /// <param name="url"> </param>
    /// <param name="userSmtp">user smtp</param>
    /// <param name="enableTrace">to enable logging from the XML tracing </param>
    /// <param name="exchangeVersion">Exchange server version used</param>
    private Uri ImpersonateUser(Uri url,string userSmtp,bool enableTrace,ExchangeVersion exchangeVersion)
    {
        Uri result = url;
        var log = "ImpersonateUser n";
        try
        {
            log += "0/8 Checking services redundancyn";
            if (Services.ContainsKey(userSmtp))
            {
                Services.Remove(userSmtp);
            }
            log += "1/8 Create a new service for " + userSmtp + "n";
            var service = new ExchangeService(exchangeVersion);

            log += "2/8 Get credentials for the servicen";
            var serviceCred = ((System.Net.NetworkCredential)(((WebCredentials)(Services.First().Value.Credentials)).Credentials));

            log += "3/8 Assign credentials to the new servicen";
            service.Credentials = new WebCredentials(serviceCred.UserName,serviceCred.Password);

            log += "4/8 TraceEnabled is" + enableTrace.ToString() + "n";
            service.TraceEnabled = enableTrace;

            log += "5/8 Get the Url for the  service with AutodiscoverUrl n";
            service.Url = url;

            log += "6/8 Assign a new ImpersonatedUserId to the new service for" + userSmtp + "n";
            service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress,userSmtp);

            try
            {
                log += "7/8 Validating the impersonationn";
                RuleCollection rulecoll = service.GetInboxRules();
            }
            catch (Exception ex)
            {
                _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUser: failed to validate the impersonation for {0}n Exception: {1}n",userSmtp,ex.Message);
                int hr = System.Runtime.InteropServices.Marshal.GetHRForException(ex);

                if (hr == -2146233088) // We do not have right to impersonate this user.
                {
                    result = null;
                    return result;
                }
                else
                {
                    _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUser(2): trying to resolve {0} with Autodiscover instead...",userSmtp);
                    result = ImpersonateUser(userSmtp,enableTrace,exchangeVersion);
                }

            }

            log += "8/8 Adding the service n";
            if (!Services.ContainsKey(userSmtp))
            {
                Services.Add(userSmtp,service);
                _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUser(2): {0} has been impersonatedn",service.ImpersonatedUserId.Id);
            }
        }
        catch (Exception ex)
        {
            _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUser(2): exception {0}n The exception occured after the following steps: n{1}",ex.Message,log);
        }
        return result;
    }

以下是调用上一个函数(即对所有用户)的代码,请记住,您应该以某种方式存储要模拟的每个帐户的电子邮件地址.

/// <summary>
        /// To Impersonate users in order to get the info from them. 
        /// </summary>
        /// <param name="userSmtps">List of users to be impersonated</param>
        /// <param name="enableTrace"> To enable logging from the XML tracing</param>
        /// <param name="exchangeVersion">Exchange server version used </param>
        public void ImpersonateUsers(ICollection<string> userSmtps)
        {
            var log = "ImpersonateUsersn";
            var firstUserSmtp = "";
            if (userSmtps != null)

                if (userSmtps.Count > 0)
                {

                    //the url for the first smtp
                    try
                    {
                        log += "1/2 Impersonating the first userSmtpn";
                        _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUsers:  Getting the Url from the autodiscovery for the first smtp {0} ",userSmtps.First());
                        bool enableTrace = Services.First().Value.TraceEnabled;

                        ExchangeVersion exchangeVersion = Services.First().Value.RequestedServerVersion;
                        firstUserSmtp = userSmtps.First();
                        var commonSmtpUrl = ImpersonateUser(userSmtps.First(),exchangeVersion);
                        if (commonSmtpUrl == null) userSmtps.Remove(firstUserSmtp);
                        // If the list contains other than the first one 
                        log += "2/2 Impersonating " + (userSmtps.Count - 1) + " userSmtpsn";

                        if (userSmtps.Count >= 1)
                        {
                            foreach (var userSmtp in userSmtps)
                            {
                                try
                                { //skip ther first one because it is already impersonated. 
                                    if (userSmtp == firstUserSmtp)
                                    {
                                        continue;
                                    }
                                    // Impersonate the users
                                    _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUsers:  Impersonating {0} ...",userSmtp);

                                        commonSmtpUrl = ImpersonateUser(userSmtp,exchangeVersion);

                                }
                                catch (Exception ex)
                                {
                                    _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUsers: Impersonating {1}n exception {0}n",userSmtp);
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        _logDevice.LogSrvMessage(1,"ExchangeLiteService: ImpersonateUsers: exception {0}n The exception occured after the following steps: n{1}",log);
                    }
                }
        }

我会把订阅部分和添加到连接,但它有点难看,很难得到.但想法只是你应该有一个连接,然后你去你做的每个服务,然后`connection.AddSubscription(streamingSubscription);其中streamingSubscription是从服务中提取的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读