背景
随着互联网的不断发展,传统的Web应用程序已经不能完全满足用户的需要。由于桌面应用程序相比Web应用程序可以实现更多的功能,并相比Web应用程序更容易访问本地资源,所以一些界于BS架构和CS架构之间的桌面应用(如瘦客户端)便应运而生,这些桌面应用在客户机上以WinForm的形式存在,而服务器侧依然是Web Server。这种体系架构需要桌面应用程序和Web Server之间可以有效通讯,一般的做法是通过Web Service 来实现桌面和Web Server之间的通讯,但Web Service的设计初衷并非是用于通讯,而是更侧重于对远程服务的调用,其体系结构相对比较复杂,如果仅仅用来通讯,难免让人感觉大材小用。介于此,我开发了一款轻量级的Web通讯组件,调用者只需调用一个函数就可以将桌面应用程序中需要通讯的对象发送到Web应用程序中,并可以从Web应用程序获得其响应的对象,如果调用者需要发送加密消息,该组件提供了发送加密消息的方法,同样是非常简单。
工作原理
图1 Web Comm 组件工作原理
如图1 所示,Web Comm 组件提供两个发送消息的方法:SendMsg和SendSecMsg,分别提供发送普通消息和发送加密消息的接口。
发送普通消息很简单,发送侧对要发送的消息对象序列化,接受侧对消息对象反序列化。
发送加密消息的过程是先获取Web Server 侧的非对称加密公钥,这个过程在进程存续期间只进行一次。然后随机产生一个DES 对称加密的密钥,消息体用对称加密密钥加密,对称加密密钥用非对称加密公钥加密,即在应用层和传输层之间加入了一个加密层,类似SSL的原理。
使用说明
桌面侧调用接口
发送普通消息接口:WebComm. CCntWebComm. SendMsg
/// <summary>
/// 发送消息
/// 通过这个方法发送消息不进行加密
/// </summary>
/// <param name="url">Web Server的Url</param>
/// <param name="evt">消息事件号</param>
/// <param name="userName">消息归属的用户名</param>
/// <param name="msg">消息体</param>
/// <param name="response">Web Server 响应后返回的消息</param>
/// <exception cref="CCommException">出错触发CCommException异常</exception>
/// <remarks>
/// msg ---> web server
/// response <--- web server
/// </remarks>
public void SendMsg(String url, int evt, object msg, out object response)
发送加密消息接口:WebComm. CCntWebComm. SendSecMsg
/// <summary>
/// 发送安全消息
/// 通过这个方法发送的消息是进行过加密的。
/// </summary>
/// <param name="url">Web Server的Url</param>
/// <param name="evt">消息事件号</param>
/// <param name="userName">消息归属的用户名</param>
/// <param name="msg">消息体</param>
/// <param name="response">Web Server 响应后返回的消息</param>
/// <exception cref="CCommException">出错触发CCommException异常</exception>
/// <remarks>
/// msg ---> web server
/// response <--- web server
/// </remarks>
public void SendSecMsg(String url, int evt, object msg, out object response)
Web Server 侧接口
Web Server 侧作为消息的接受侧只需要将接受消息的页面做如下处理,即可以实现和桌面应用程序通讯。
1、 页面程序从 WebComm.CWSMsgBase 继承
例如 public partial class _Default : WebComm.CWSMsgBase
2、 重载Page_Load
new protected void Page_Load(object sender, EventArgs e)
{
base.Page_Load(sender, e);
}
3、 重载消息接受函数 ProcessMessage
protected override void ProcessMessage(int evt, object msg, out object response)
{
//处理接受的消息
}
错误码
[Serializable]
public enum T_CommError
{
Success = 0,
/// <summary>
/// 序列化错误
/// </summary>
SerializationFail = 100,
/// <summary>
/// 反序列化
/// </summary>
DeserializationFail = 101,
/// <summary>
/// DES 加密错误
/// </summary>
DesEncryptFail = 102,
/// <summary>
/// DES 解密错误
/// </summary>
DesDecryptFail = 103,
/// <summary>
/// 流转换为字符串错误
/// </summary>
StreamToStringFail = 104,
/// <summary>
/// 字符串转换为流错误
/// </summary>
StringToStreamFail = 105,
/// <summary>
/// 字符串到Base64错误
/// </summary>
StringToBase64Fail = 106,
/// <summary>
/// Base64到字符串错误
/// </summary>
Base64ToStringFail = 107,
/// <summary>
/// 无效的响应
/// </summary>
InvalidResponse = 108,
/// <summary>
/// 空的公钥
/// </summary>
EmptyPubkey = 109,
/// <summary>
/// 无效的公钥
/// </summary>
InvalidPubkey = 110,
/// <summary>
/// 无效的事件号
/// </summary>
InvalidEvent = 111,
/// <summary>
/// 连接错误
/// </summary>
ConnectFail = 500,
////////////////////////////////////////////////////////
//服务器侧错误
/// <summary>
/// 读取参数错误
/// </summary>
SvrParaFail = 10000,
/// <summary>
/// RSA 解密错误
/// </summary>
RSAFail = 10001,