上一篇中我们已经定义好了气象中心的一些服务契约与数据契约,对不同需要的用户提供了不同的服务接口,但是麻烦的事情又来了...

       首先,两个服务放在个环境中的需要共享内存,如一些常用的代码映射表、订阅用户列表、气象中心各个城市的天气信息等。这种情况可以采取设计模式中的单例模式来实现,简单的来说就是将公共的信息以及对公共信息的操作一并抽取出来,放到一个共享实例中,这个实例是静态并且对两个服务接口公开,如:

      1. 建立共享实例

         public static class SystemVars   

        {       

             #region 公共信息

             public static bool IsLoading = false; //是否加载完成    

             public static List<UserInfo> lstUsers = new List<UserInfo>(); //当前订阅服务的用户    

             public static List<Login> lstStations = new List<Login>(); //当前气象站点

             public static List<Item> lstCities = new List<Item>();//当前能提供的天气服务的城市列表  

             public static List<Item> lstWeatherInfos = new List<Item>();   //天气映射

             public static List<Weather> lstCityWeathers = new List<Weather>();//城市实时天气表       

             #endregion

             #region 公共操作

             public static void IniData()
             {
                   if (IsLoading) return;
                   IsLoading = true;

                   IniCities();//加载城市信息        

                   IniWeatherInfos();//加载天气映射   

                   //... 其它加载

             }

              static void IniCities()//加载城市映射

              {

                   //...

              }

              static void  IniWeatherInfos()//加载天气映射

              {

                    //...

              }

              public static Item[] GetCityEnum(Login login) //取城市映射

              {

                   //...

              }

               public static Item[] GetWeatherEnum(Login login) //取天气映射
              {

                    //...

               }

               public static void UpdateWeather(Weather weather)//通知用户更新天气
               {
                      //找到那些订阅了该城市天气的用户
                      List<UserInfo> users = SystemVars.lstUsers.FindAll(x => x.Cities.Contains(weather.CityCode));
                      foreach (var user in users)
                      {
                            if (user.Callback != null)  user.Callback.UpdateWeather(weather); 
                     }
                }

               //...其它

             #endregion

      

      1. 修改两个服务的初始化,以便建立共享信息,如:

          public ClientWeatherServer()
         {
               //直到加载完成才初始化完成
               SystemVars.IniData();
         }

          public StationWeatherServer()
         {
               //直到加载完成才初始化完成 
               SystemVars.IniData();
         }

 

       其次,两个服务的发布问题,比如每个服务根据不同的业务需要可能采取不同的绑定协议,像对气象站公开的服务我们可以采取http,而对于有回调的

向订阅用户公开的服务我们就应该采取net.tcp或者其它支持回调接口的协议。

       要解决这问题,其实只要对app.config配置文件作相应修改就行了(完整App.cong在我的文件列表AppConfig.rar中),如:

      <services>
      <service name="WeatherServices.StationWeatherServer" behaviorConfiguration="httpBehavior">
        <host>
           <baseAddresses>
               <add baseAddress="http://localhost:8065" />
           </baseAddresses>
         </host>
         <endpoint address="" binding="basicHttpBinding" contract="WeatherServices.IStationWeatherServer" />
         <endpoint address="StationWeatherServer" binding="mexHttpBinding" contract="IMetadataExchange" />
       </service>
       <service name="WeatherServices.ClientWeatherServer" behaviorConfiguration="tcpBehavior">
          <host>
              <baseAddresses>
                 <add baseAddress="net.tcp://localhost:8066" />
             </baseAddresses>
          </host>
          <endpoint address="" binding="netTcpBinding" bindingConfiguration="tcpBinding" contract="WeatherServices.IClientWeatherServer" />
          <endpoint address="ClientWeatherServer" binding="mexTcpBinding" contract="IMetadataExchange" />
        </service>
      </services>

       最后,实现服务内容,如在服务中心在接收到气象站发来的天气变化信息时,就立即通知订阅了该城市天气的用户,如:

       public class StationWeatherServer : IStationWeatherServer
       {

              //...其它操作

             public void UpdateWeather(Weather weather, Login login)
            {

                   //1. 验证登录是否合法

                   //...

                   //2. 更新服务中心气象列表

                   //...

                   //3. 通知用户更新

                   SystemVars.UpdateWeather(weather);

            }

       }