/// <summary> /// 接收注册中心的消息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void m_CometClient_OnReceiveNotify(object sender, CometEventArgs e) { try { if (e.Type == CometEventType.ReceiveMessage) // 接收到来自服务器的配置信息 { CometMessage rm = XmlUtil.LoadObjFromXML <CometMessage>(e.Response); if (rm.Action == CometMessageAction.ServiceConfig) { OnReceiveServiceConfig(rm); } else if (rm.Action == CometMessageAction.ListRegistryClient) { OnListRegistryClient(rm); } } else if (e.Type == CometEventType.Connected) // 当和服务器取得联系时发送消费者配置文件到服务端 { XTrace.WriteLine("成功连接到注册中心。"); m_CometClient.SendData(CometMessageAction.Hello, m_ESBProxy.ConsumerConfig.ToXml()); } else if (e.Type == CometEventType.Lost) // 当和注册中心断开连接时 { Console.WriteLine("和注册中心断开连接。"); ReConnect(); } } catch (Exception ex) { XTrace.WriteLine("接收注册中心消息时发生错误:" + ex.ToString()); } }
/// <summary> /// 向单个客户端发送数据 /// </summary> /// <param name="rsClient"></param> /// <param name="data"></param> /// <param name="isAsync">默认为异步调用</param> public void SendData(RegistryClient registryClient, CometMessageAction action, String data, Boolean isAsync = true) { try { CometMessage rm = new CometMessage() { Action = action, MessageBody = data, IsAsync = isAsync }; String messageData = XmlUtil.SaveXmlFromObj <CometMessage>(rm); Console.WriteLine("发送数据:{0}", messageData); Byte[] msg = Encoding.UTF8.GetBytes(messageData); registryClient.Socket.BeginSend(msg, 0, msg.Length, SocketFlags.None, new AsyncCallback(SendCallback), registryClient); } catch (Exception ex) { XTrace.WriteLine("发送数据时发生异常:" + ex.ToString()); lock (m_RegistryClients) { m_RegistryClients.Remove(registryClient); registryClient.Dispose(); } } }
/// <summary> /// 增对不同的客户端和消息类型进行处理 /// </summary> /// <param name="regClient"></param> /// <param name="regMessage"></param> public void Process(RegistryClient regClient, CometMessage regMessage) { if (regMessage.Action == CometMessageAction.Hello) { ConsumerConfig consumerConfig = XmlUtil.LoadObjFromXML <ConsumerConfig>(regMessage.MessageBody); regClient.ConsumerConfig = consumerConfig; regClient.ProcessorID = regMessage.ProcessorID; regClient.DotNetFramworkVersion = regMessage.DotNetFramworkVersion; regClient.OSVersion = regMessage.OSVersion; regClient.ClientApplicationName = consumerConfig.ApplicationName; ESBConfig esbConfig = GetESBConfig(regClient); m_RegistryCenter.SendData(regClient, CometMessageAction.ServiceConfig, esbConfig.ToXml(), regMessage.IsAsync); } else if (regMessage.Action == CometMessageAction.ListRegistryClient) { String message = XmlUtil.SaveXmlFromObj <List <RegistryClient> >(m_RegistryCenter.RegistryClients); m_RegistryCenter.SendData(regClient, CometMessageAction.ListRegistryClient, message, regMessage.IsAsync); } else if (regMessage.Action == CometMessageAction.ResendConfig)//--管理中心向每个客户端发送配置文件 { foreach (var item in m_RegistryCenter.RegistryClients) { if (item.RegistryClientType == CometClientType.Consumer || item.RegistryClientType == CometClientType.CallCenter || item.RegistryClientType == CometClientType.Monitor || item.RegistryClientType == CometClientType.QueueCenter || item.RegistryClientType == CometClientType.Portal) { ESBConfig esbConfig = GetESBConfig(item); m_RegistryCenter.SendData(item, CometMessageAction.ServiceConfig, esbConfig.ToXml()); } } } }
/// <summary> /// 接收注册中心的消息 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void m_CometClient_OnReceiveNotify(object sender, CometEventArgs e) { try { if (e.Type == CometEventType.ReceiveMessage) // 接收到来自服务器的配置信息 { CometMessage rm = XmlUtil.LoadObjFromXML <CometMessage>(e.Response); if (rm.Action == CometMessageAction.Publish) { List <ServiceMonitor> lstServiceMonitor = XmlUtil.LoadObjFromXML <List <ServiceMonitor> >(rm.MessageBody); if (OnMonitorStatPublish != null) { OnMonitorStatPublish(this, new MonitorStatEventArgs(lstServiceMonitor)); } } } else if (e.Type == CometEventType.Connected) { XTrace.WriteLine("成功连接到监控中心。"); } else if (e.Type == CometEventType.Lost) // 当和监控中心断开连接时 { Console.WriteLine("和监控中心断开连接, 5秒钟后将重新连接。"); ReConnect(); } } catch (Exception ex) { Console.WriteLine("接收监控中心消息时发生错误:" + ex.ToString()); } }
/// <summary> /// 接收到注册中心的连接客户端列表 /// </summary> /// <param name="rm"></param> private void OnListRegistryClient(CometMessage rm) { m_RegistryClientList = XmlUtil.LoadObjFromXML <List <RegistryClient> >(rm.MessageBody); //--如果是同步调用,则需要在消息返回时释放信号 if (!rm.IsAsync) { m_AutoResetEvent.Set(); } }
/// <summary> /// 接收请求回调函数 /// </summary> /// <param name="ar"></param> private void ReceiveCallback(IAsyncResult ar) { RegistryClient registryClient = (RegistryClient)ar.AsyncState; try { int dataLength = registryClient.Socket.EndReceive(ar); if (dataLength == 0) { Console.WriteLine("接收客户端:{0}已经断开连接。", registryClient.ClientIP); lock (m_RegistryClients){ m_RegistryClients.Remove(registryClient); registryClient.Dispose(); } } else { String data = Encoding.UTF8.GetString(registryClient.ReceiveBuffer, 0, dataLength); Console.WriteLine("接收客户端:{0}发送的数据:{1}。", registryClient.ClientIP, data); //--解析来自客户端的类型 CometMessage regMessage = XmlUtil.LoadObjFromXML <CometMessage>(data); registryClient.RegistryClientType = regMessage.ClientType; registryClient.ClientVersion = regMessage.ClientVersion; registryClient.ClearBuffer(); registryClient.Socket.BeginReceive(registryClient.ReceiveBuffer, 0, registryClient.ReceiveBuffer.Length , SocketFlags.None, new AsyncCallback(ReceiveCallback), registryClient); //--由消息处理器进行处理 m_MessageProcessor.Process(registryClient, regMessage); }; } catch (Exception ex) { XTrace.WriteLine("接收数据时发生异常:" + ex.ToString()); lock (m_RegistryClients) { m_RegistryClients.Remove(registryClient); registryClient.Dispose(); } } }
// Возвращаем сообщение каждому подключенному клиенту public static void PushMessage(CometMessage message) { lock (_lock) { // Пробегаем по списку всех подключенных клиентов foreach (CometAsyncState clientState in _clientStateList) { if (clientState.CurrentContext.Session != null) { // И пишем в выходной поток текущее сообщение clientState.CurrentContext.Response.Write(message.Serialize()); // После чего завершаем запрос - вот именно после этого результаты // запроса пойдут ко всем подключенным клиентам clientState.CompleteRequest(); } } } }
/// <summary> /// 接收到服务配置信息 /// </summary> private void OnReceiveServiceConfig(CometMessage rm) { //--如果ESBConfig为NULL,则说明注册中心还没连上 if (m_ESBProxy.ESBConfig == null) { m_ESBProxy.ESBConfig = XmlUtil.LoadObjFromXML <ESBConfig>(rm.MessageBody); m_ESBProxy.MessageQueueClient.ConnectAsync(); } else { //--从返回消息中加载ESBConfig配置文件 m_ESBProxy.ESBConfig = XmlUtil.LoadObjFromXML <ESBConfig>(rm.MessageBody); if (m_ESBProxy.ESBConfig != null) { m_ESBProxy.Status = ESBProxy.ESBProxyStatus.Ready; } } //--如果是同步调用,则需要在消息返回时释放信号 if (!rm.IsAsync) { m_AutoResetEvent.Set(); } //--异步将配置文件序列化到本地存储 ThreadPoolX.QueueUserWorkItem(x => { m_ConfigurationManager.SaveESBConfig(m_ESBProxy.ESBConfig); }); //--如果客户端订阅了这个事件,则触发并送上最新的ESBConfig if (OnServiceConfigChange != null) { OnServiceConfigChange(this, new RegistryEventArgs() { ESBConfig = m_ESBProxy.ESBConfig }); } }