最近在学习WCF以及设计模式....,书看了几本,有PDF的也有书店买的,虽然感觉懂了,但要真正应用起来就感觉无处下手。
于是决定结合设计模式与WCF技术开发一个例子程序,主要功能是用于模拟气象站发布天天气以及用户订阅天气的一种应用。
本程序的主要要实现以下几个功能:
1. 气象服务中心,其主要由以下部分组成:
A. 为气象监测站点提供天气更新接口,一旦某监测站监测的实时数据发生变化,立即通知订阅了天气的用户。
B. 为用户订阅天气提供接口,包括订阅与取消等功能。
2. 气象监测站,其主要由以下部分组成:
A. 监测气象变化,并主动发起会话请求,更新天气信息至气象服务中心。
B. 参照预警标准,向发订阅天气的用户发布预警消息。
3. 订阅天气用户,其主要由以下部分组成:
A. 可根据气象中心提供的接口,订阅某些城市的天气信息。
B. 不再需要订阅时可以取消订阅。
C. 实时接收气象中心推送天气信息并展示。
气象监测站、气象服务中心、订阅天气用户的关系图如下:
通过以上分析,我们可以知道本程序正好可以运用设计模式中的观察者模式来设计实现。
现在我们可以开始动手了....
首先,建立服务中心,其主要是要面向气象站、订阅用户提供服务,那么我们可以实现两个服务接口:
A. 建立WCF工程,取名为:WeatherServices
B. 建立两个服务接口,分别为:
1. 为气象站服务的接口
[ServiceContract]
public interface IStationWeatherServer //为气象站服务的接口
{
[OperationContract]
void UpdateWeather(Weather weather, Login login);//更新天气信息
[OperationContract]
void UpdateMessage(string message, Login login);//广播消息
}
2. 为订阅天气的用户服务的接口
[ServiceContract]
public interface IStationWeatherServer //为订阅天气的用户服务的接口
{
[OperationContract]
UserInfo BookWeather(UserInfo user);//(订阅时 user中应包含订阅城市列表,若订阅成功,则返回服务中心分配的登录名称与密码)
[OperationContract]
bool CancelWeather(Login login);//取消订阅
[OperationContract]
Weather[] GetWeather(Login login);//订阅成功后获取天气
}
C. 定义一组数据契约:包括天气对象、登录对象等,如:
1. 基础类
[DataContract]
public class Item : IItem
{
[DataMember]
public string Code{set;get;}
[DataMember]
public string Name{set;get;}
}
2. 登录
[DataContract]
public class Login: Item, ILogin
{
[DataMember]
public string Password{set;get;}
}
3. 订阅用户
[DataContract]
public class UserInfo : Login, IUserInfo
{
[DataMember]
public string[] Cities
}
4. 天气信息
[DataContract]
public class Weather:IWeather
{
[DataMember]
public string Date {set;get;}
[DataMember]
public string CityCode {set;get;}
[DataMember]
public double Temperature{set;get;}
...
}
D. 扩展两个服务接口,分别为其添加获取城市映射列表、天气映射列表等代码信息,如:
1. 城市映射列表
[OperationContract]
Item[] GetCityEnum(Login login);
2. 天气映射列表
[OperationContract]
Item[] GetWeatherEnum(Login login);
E. 为了向订阅天气的用户推送消息,我们还得定义一个单向的回调函数ICallback,并修改接口IStationWeatherServer的属于为:
1. 修改接口IStationWeatherServer
[ServiceContract(CallbackContract = typeof(ICallback))] //标识该接口是带回调函数的
public interface IClientWeatherServer
{
...
}
2. 用于回调的契约 (订阅用户在引用ClientWeatherServer服务后,需要实现回调接口)
public interface ICallback
{
[OperationContract(IsOneWay = true)]
void UpdateWeather(Weather weather); //推送天气
[OperationContract(IsOneWay = true)]
void UpdateMessage(string message); //推送消息
}
3. 修改用户信息契约,增加一个用于保存连接的属性,以方便推送天气或者消息时使用
[DataContract]
public class UserInfo : Login, IUserInfo
{
public ICallback Callback{set;get;}//这个属性不用加[DataMember],因为只在服务器上使用不公开
}