Exemple #1
0
        /// <summary>
        /// 订阅服务,并且指定服务端回调客户端函数
        /// </summary>
        /// <typeparam name="T">服务器端推送的消息的结果类型</typeparam>
        /// <typeparam name="TCallbackPara">服务器端回调客户端的方法的参数类型</typeparam>
        /// <typeparam name="TCallbackResult">服务器端回调客户端的方法的结果类型</typeparam>
        /// <param name="request">服务请求对象</param>
        /// <param name="action">用于处理服务器推送的消息的方法</param>
        /// <param name="serverCallback">用于处理服务器回调结果的函数</param>
        /// <returns>消息编号</returns>
        public int Subscribe <T, TCallbackPara, TCallbackResult>(ServiceRequest request, Action <MessageConverter <T> > action, MyFunc <TCallbackPara, TCallbackResult> serverCallback)
        {
            request.ResultType   = typeof(T);
            request.RequestModel = RequestModel.Publish;
            DataType resultDataType = MessageConverter <T> .GetResponseDataType();

            return(Subscribe(request.ServiceUrl, request.ResultType,
                             remoteMsg =>
            {
                string errMsg = ServiceConst.GetServiceErrorMessage(remoteMsg);
                if (errMsg != string.Empty)
                {
                    RaiseSubscriberError(this, new MessageEventArgs(errMsg));
                }
                else
                {
                    MessageConverter <T> convert = new MessageConverter <T>(remoteMsg, resultDataType);
                    if (action != null)
                    {
                        action(convert);
                    }
                }
            },
                             para =>
            {
                MessageConverter <TCallbackPara> convert = new MessageConverter <TCallbackPara>(para);
                TCallbackResult result = serverCallback(convert.Result);

                MessageConverter <TCallbackResult> convertFunResult = new MessageConverter <TCallbackResult>();
                string strResult = convertFunResult.Serialize(result);
                //检查转换是否成功,convertFunResult.MessageText 可以获取结果的原始值
                return strResult;
            }
                             ));
        }
Exemple #2
0
        /// <summary>
        /// 消息发布线程准备就绪,开启业务工作线程
        /// </summary>
        protected internal void Ready()
        {
            ServiceEventSource ses = this.Context.PublishEventSource;

            if (ses.EventWork != null)
            {
                Task.Factory.StartNew(() =>
                {
                    try
                    {
                        ses.EventWork();
                        Console.WriteLine("事件源对象的工作任务处理完成,即将停止事件处理。");
                    }
                    catch (Exception ex)
                    {
                        this.publishResult = ServiceConst.CreateServiceErrorMessage(ex.Message);
                        Console.WriteLine("事件源对象执行事件操作错误,即将停止事件处理!");
                        Program.Processer_ServiceErrorEvent(this, new ServiceErrorEventArgs(ex, "事件源对象执行事件操作错误"));
                    }

                    published = false;
                    //事件推送线程收到信号,开始工作
                    base.SetPublishEvent();
                    System.Threading.Thread.Sleep(1000);
                    ses.DeActive();
                    lastPublishTime = DateTime.Now;
                });
            }
        }
Exemple #3
0
        private void ProcessRemoteMessage <T>(string remoteMsg, DataType resultDataType, Connection conn, Action <T> action)
        {
            if (conn != null)
            {
                conn.Close();
            }
            string errMsg = ServiceConst.GetServiceErrorMessage(remoteMsg);

            if (errMsg != string.Empty)
            {
                RaiseSubscriberError(this, new MessageEventArgs(errMsg));
            }
            else
            {
                MessageConverter <T> convert = new MessageConverter <T>(remoteMsg, resultDataType);
                if (convert.Succeed)
                {
                    if (action != null)
                    {
                        action(convert.Result);
                    }
                }
                else if (remoteMsg == "") //处理无返回值
                {
                    if (action != null)
                    {
                        action(convert.Result);
                    }
                }
                else
                {
                    RaiseSubscriberError(convert, new MessageEventArgs(convert.ErrorMessage));
                }
            }
        }
Exemple #4
0
        /// <summary>
        /// 请求一个服务,然后异步处理结果。注意如果没有订阅异常处理事件(ErrorMessage),将在Task 上抛出异常。
        /// </summary>
        /// <typeparam name="T">服务方法的结果类型</typeparam>
        /// <param name="reqSrvUrl">服务的地址</param>
        /// <param name="resultDataType">服务返回的数据类型</param>
        /// <returns>服务结果</returns>
        public Task <T> RequestServiceAsync <T>(string reqSrvUrl, DataType resultDataType)
        {
            var        tcs  = new TaskCompletionSource <T>();
            Connection conn = new Connection(this.ServiceBaseUri, this.UseConnectionPool);

            conn.ErrorMessage += new EventHandler <MessageEventArgs>(
                (object sender, MessageEventArgs e) => {
                if (this.ErrorMessage != null)
                {
                    this.ErrorMessage(sender, new MessageEventArgs(e.MessageText));
                    tcs.SetCanceled();
                }
                else
                {
                    tcs.SetException(new Exception(e.MessageText));
                }
            }
                );


            if (conn.Open())
            {
                conn.RequestService(reqSrvUrl, null, (remoteMsg) =>
                {
                    conn.Close();
                    string errMsg = ServiceConst.GetServiceErrorMessage(remoteMsg);
                    if (errMsg != string.Empty)
                    {
                        if (this.ErrorMessage != null)
                        {
                            this.ErrorMessage(this, new MessageEventArgs(errMsg));
                            tcs.SetCanceled();
                        }
                        else
                        {
                            //即使抛出了异常,也必须设置任务线程的异常,否则异步方法没法返回
                            tcs.SetException(new Exception(errMsg));
                        }
                    }
                    else
                    {
                        MessageConverter <T> convert = new MessageConverter <T>(remoteMsg, resultDataType);
                        if (convert.Succeed)
                        {
                            tcs.SetResult(convert.Result);
                        }
                        else
                        {
                            this.RaiseSubscriberError(convert, new MessageEventArgs("resultDataType 指定错误"));
                        }
                    }
                });
            }
            else
            {
                conn.Close();
                tcs.SetCanceled();
            }
            return(tcs.Task);
        }
Exemple #5
0
 private void ProcessServiceError(Exception ex, string errMessage = "")
 {
     //Console.WriteLine("执行服务方法错误:{0}", ex.Message);
     this.Response.Write(ServiceConst.CreateServiceErrorMessage(ex.Message));
     this.Response.End();
     this.OnServiceError(ex, string.Format(
                             "执行服务方法错误:{0}\r\n源错误信息:{1},\r\n请求的Uri:\r\n{2},\r\n{3}:{4},{5}\r\n",
                             errMessage,
                             ex.Message,
                             this.Request.ServiceUrl,
                             this.Request.ClientIP,
                             this.Request.ClientPort,
                             this.Request.ClientIdentity)
                         );
 }
Exemple #6
0
        /// <summary>
        /// 以同步的方式(阻塞),获取服务执行的结果消息
        /// </summary>
        /// <typeparam name="T">消息类型</typeparam>
        /// <param name="reqSrvUrl">服务地址</param>
        /// <param name="resultDataType">消息的数据类型</param>
        /// <returns>消息转换器对象,如果不成功,返回空值</returns>
        public MessageConverter <T> GetServiceMessage <T>(string reqSrvUrl, DataType resultDataType)
        {
            CheckConnect();
            //ServiceSubscriber.SendMessage(reqSrvUrl);

            string remoteMsg = ServiceSubscriber.RequestMessage(reqSrvUrl);
            string errMsg    = ServiceConst.GetServiceErrorMessage(remoteMsg);

            if (errMsg != string.Empty)
            {
                RaiseSubscriberError(this, new MessageEventArgs(errMsg));
                return(null);
            }
            else
            {
                MessageConverter <T> convert = new MessageConverter <T>(remoteMsg, resultDataType);
                return(convert);
            }
        }
Exemple #7
0
        private void ProcessRemoteMsgInTask <T>(DataType resultDataType, string remoteMsg, TaskCompletionSource <T> tcs)
        {
            string errMsg = ServiceConst.GetServiceErrorMessage(remoteMsg);

            if (errMsg != string.Empty)
            {
                if (this.ErrorMessage != null)
                {
                    this.ErrorMessage(this, new MessageEventArgs(errMsg));
                    tcs.SetCanceled();
                }
                else
                {
                    //即使抛出了异常,也必须设置任务线程的异常,否则异步方法没法返回
                    tcs.SetException(new Exception(errMsg));
                }
            }
            else
            {
                MessageConverter <T> convert = new MessageConverter <T>(remoteMsg, resultDataType);
                if (convert.Succeed)
                {
                    tcs.SetResult(convert.Result);
                }
                else
                {
                    ////服务端Task<T> 返回类型,应该在服务端处理完结果
                    //
                    errMsg = "resultDataType 指定错误:" + convert.ErrorMessage;
                    if (this.ErrorMessage != null)
                    {
                        this.ErrorMessage(this, new MessageEventArgs(errMsg));
                        tcs.SetCanceled();
                    }
                    else
                    {
                        //即使抛出了异常,也必须设置任务线程的异常,否则异步方法没法返回
                        tcs.SetException(new Exception(errMsg));
                    }
                }
            }
        }
Exemple #8
0
 /// <summary>
 /// 发起订阅,并处理来自服务器的消息(订阅的数据类型)
 /// </summary>
 /// <typeparam name="T">服务返回的结果对象类型,仅供服务器端使用</typeparam>
 /// <typeparam name="T2">服务结果真正要转换成最终使用的对象类型</typeparam>
 /// <param name="request">服务请求对象</param>
 /// <param name="resultDataType">消息的数据类型</param>
 /// <param name="action">自定义的处理方法</param>
 /// <returns>消息标识,如果为0,则订阅未成功</returns>
 public int Subscribe <T, T2>(ServiceRequest request, DataType resultDataType, Action <MessageConverter <T2> > action)
 {
     request.ResultType = typeof(T);
     return(Subscribe(request, remoteMsg =>
     {
         string errMsg = ServiceConst.GetServiceErrorMessage(remoteMsg);
         if (errMsg != string.Empty)
         {
             RaiseSubscriberError(this, new MessageEventArgs(errMsg));
         }
         else
         {
             MessageConverter <T2> convert = new MessageConverter <T2>(remoteMsg, resultDataType);
             if (action != null)
             {
                 action(convert);
             }
         }
     }));
 }
Exemple #9
0
        protected override void Process()
        {
            string message  = this.Message;
            string identity = this.SubscriberInfo.Identity;

            string   processMesssage = string.Empty;
            DateTime beginTime       = DateTime.Now;

            processMesssage = string.Format("[{0}]正在处理服务请求--From: {1}:{2},Identity:{3}\r\n>>[PMID:{4}]{5}",
                                            beginTime.ToString("yyyy-MM-dd HH:mm:ss.fff"),
                                            this.SubscriberInfo.FromIP, this.SubscriberInfo.FromPort, identity,
                                            this.SubscriberInfo.MessageID,
                                            this.Message.Length > 256 ? this.Message.Substring(0, 256) : this.Message);
            Console.WriteLine(processMesssage);

            int msgId = this.SubscriberInfo.MessageID;//执行完服务方法后,MessageID 可能被另外一个线程改变
            //执行服务方法的时候,由服务方法指名是否需要维持会话状态
            ServiceContext context = new ServiceContext(message);

            //如果当前请求是 发布-订阅模式,多个订阅端使用一个发布对象实例
            if (context.Request.RequestModel == RequestModel.Publish || context.Request.RequestModel == RequestModel.ServiceEvent)
            {
                if (PublisherFactory.Instance.Contains(context))  //已经订阅过
                {
                    ServicePublisher publisher = PublisherFactory.Instance.GetPublisher(context);
                    if (publisher.TaskIsRunning)
                    {
                        publisher.SubscriberInfoList.Add(this.SubscriberInfo);
                        processMesssage = string.Format("\r\n[{0}]当前监听器已经加入消息发布线程, {1}:{2},Identity:{3}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), this.SubscriberInfo.FromIP, this.SubscriberInfo.FromPort, this.SubscriberInfo.Identity);
                        Console.WriteLine(processMesssage);
                        return;
                    }
                }
            }

            context.Host = Program.Host;
            context.ServiceErrorEvent     += new EventHandler <ServiceErrorEventArgs>(context_ServiceErrorEvent);
            context.Request.ClientIP       = this.SubscriberInfo.FromIP;
            context.Request.ClientPort     = this.SubscriberInfo.FromPort;
            context.Request.ClientIdentity = this.SubscriberInfo.Identity;

            context.User = MessageProcessBase.GetServiceIdentity(this.SubscriberInfo._innerListener);

            context.GetMessageFun = strPara =>
            {
                MessageListener currLst = MessageCenter.Instance.GetListener(this.SubscriberInfo.FromIP, this.SubscriberInfo.FromPort);
                if (currLst == null)
                {
                    throw new NullReferenceException("监听器不存在!");
                }
                return(currLst.CallBackFunction(msgId, strPara));
            };

            context.PreGetMessageFun = strPara =>
            {
                MessageListener currLst = MessageCenter.Instance.GetListener(this.SubscriberInfo.FromIP, this.SubscriberInfo.FromPort);
                if (currLst == null)
                {
                    throw new NullReferenceException("监听器不存在!");
                }
                return(currLst.PreCallBackFunction(msgId, strPara));
            };

            string result   = string.Empty;
            bool   noResult = false;

            context.InitRequestParameters();
            if (!context.HasError)
            {
                //Console.WriteLine("Process Service begin...");
                context.ProcessService(this.SubscriberInfo.SessionID);
                //Console.WriteLine("Process Service ok...");
                result   = context.Response.AllText;
                noResult = context.NoResultRecord(result);
            }
            else
            {
                result = ServiceConst.CreateServiceErrorMessage(context.ErrorMessage);
                //base.OnServiceError(context, new ServiceErrorEventArgs(context.ErrorMessage));
            }

            DateTime endTime = DateTime.Now;

            processMesssage = string.Format("[{0}]请求处理完毕({1}ms)--To: {2}:{3},Identity:{4}\r\n>>[PMID:{5}]消息长度:{6} -------",
                                            endTime.ToString("yyyy-MM-dd HH:mm:ss.fff"),
                                            endTime.Subtract(beginTime).TotalMilliseconds,
                                            this.SubscriberInfo.FromIP, this.SubscriberInfo.FromPort, identity,
                                            this.SubscriberInfo.MessageID,
                                            noResult ? "[Empty Result]" : result.Length.ToString("###,###") + "字节");
            Console.WriteLine(processMesssage);
            //此处内容可能很大,不能全程输出
            if (context.Response.ResultType == typeof(byte[]))
            {
                Console.WriteLine("[byte Content]");
            }
            else
            {
                Console.WriteLine("result:{0}", result.Length > 100 ? result.Substring(0, 100) + " ..." : result);
            }

            MessageListener currLstn = MessageCenter.Instance.GetListener(this.SubscriberInfo.FromIP, this.SubscriberInfo.FromPort);

            if (currLstn == null)
            {
                processMesssage = "Error:监听器未找到,已取消发送消息。请求源:" + this.SubscriberInfo.Message;
                Console.WriteLine(processMesssage);
                return;
            }
            if (context.Request.RequestModel == RequestModel.GetService)
            {
                //对于请求-响应模式,处理完服务以后,始终会回调客户端的方法(如果提供的话)
                if (MessageCenter.Instance.ResponseMessage(currLstn, msgId, result))
                {
                    Console.WriteLine("Reponse Message OK.");
                }
            }
            else
            {
                //订阅模式,仅在服务处理有结果的情况下,才给客户端发布数据。

                if (!noResult)
                {
                    if (MessageCenter.Instance.NotifyOneMessage(currLstn, msgId, result))
                    {
                        Console.WriteLine("Publish Message OK.");
                    }
                    else
                    {
                        Console.WriteLine("Publish no result.");
                    }
                }
                if (!context.HasError)
                {
                    StartPublishWorker(context);//把Host传递进去
                    processMesssage = string.Format("\r\n[{0}]当前监听器已经加入工作线程, {1}:{2},Identity:{3}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"), this.SubscriberInfo.FromIP, this.SubscriberInfo.FromPort, this.SubscriberInfo.Identity);
                    Console.WriteLine(processMesssage);
                }
            }
        }
Exemple #10
0
        /// <summary>
        /// 异步请求服务,并允许服务在执行过程中,回调客户端函数。不支持 KeepAlive 指定使用长连接。
        /// </summary>
        /// <typeparam name="T">服务的结果返回类型</typeparam>
        /// <typeparam name="TFunPara">回调函数的参数类型</typeparam>
        /// <typeparam name="TFunResult">回调函数的结果类型</typeparam>
        /// <param name="reqSrvUrl">请求服务的URL地址</param>
        /// <param name="resultDataType">结果数据类型</param>
        /// <param name="function">回调函数</param>
        /// <returns>异步任务对象</returns>
        public Task <T> RequestServiceAsync <T, TFunPara, TFunResult>(string reqSrvUrl, DataType resultDataType, MyFunc <TFunPara, TFunResult> function)
        {
            var        tcs  = new TaskCompletionSource <T>();
            Connection conn = new Connection(this.ServiceBaseUri, this.UseConnectionPool);

            conn.UserName      = this.ConnectionUserName;
            conn.Password      = this.ConnectionPassword;
            conn.RegisterData  = this.RegisterData;
            conn.ErrorMessage += new EventHandler <MessageEventArgs>(
                (object sender, MessageEventArgs e) =>
            {
                if (this.ErrorMessage != null)
                {
                    this.ErrorMessage(sender, new MessageEventArgs(e.MessageText));
                    tcs.SetCanceled();
                }
                else
                {
                    tcs.SetException(new Exception(e.MessageText));
                }
            }
                );


            if (conn.Open())
            {
                conn.RequestService(reqSrvUrl, null, (remoteMsg) =>
                {
                    conn.Close();
                    string errMsg = ServiceConst.GetServiceErrorMessage(remoteMsg);
                    if (errMsg != string.Empty)
                    {
                        if (this.ErrorMessage != null)
                        {
                            this.ErrorMessage(this, new MessageEventArgs(errMsg));
                            tcs.SetCanceled();
                        }
                        else
                        {
                            //即使抛出了异常,也必须设置任务线程的异常,否则异步方法没法返回
                            tcs.SetException(new Exception(errMsg));
                        }
                    }
                    else
                    {
                        MessageConverter <T> convert = new MessageConverter <T>(remoteMsg, resultDataType);

                        tcs.SetResult(convert.Result);
                    }
                },
                                    para =>
                {
                    MessageConverter <TFunPara> convert = new MessageConverter <TFunPara>(para);
                    TFunResult result = function(convert.Result);

                    MessageConverter <TFunResult> convertFunResult = new MessageConverter <TFunResult>();
                    string strResult = convertFunResult.Serialize(result);
                    //检查转换是否成功,convertFunResult.MessageText 可以获取结果的原始值
                    return(strResult);
                }

                                    );
            }
            else
            {
                conn.Close();
                tcs.SetCanceled();
            }
            return(tcs.Task);
        }