Remoting and MSMQ 结合做的一个DEMO
真的非常感谢CnBlogs.com,因为有很多教程里写的知识点并不全面,而且也没附带例子.通过这里我学习到了很多很多.希望网站能越办越好哦.
下面是我学习分布式开发时写的一个小demo,当然功能有限,技术也很低.希望大师们能拍拍砖,不吝赐教.呵呵
软件运行的一个截图
下面说说流程吧,
1:利用public static object CreateInstance(Type type, object[] args, object[] activationAttributes);方法创建一个类(并激活自定义的构造函数)
2:利用MSMQ异步接收事件参数来触发remoting的事件
大约就是这样的里程,不过看上去蛮简单的,可里面用到很多MSMQ和remoting事件的知识点哦..下面是一段在remoting里面调用的dll原代码
客户端调用如下
下面是我学习分布式开发时写的一个小demo,当然功能有限,技术也很低.希望大师们能拍拍砖,不吝赐教.呵呵
软件运行的一个截图
下面说说流程吧,
1:利用public static object CreateInstance(Type type, object[] args, object[] activationAttributes);方法创建一个类(并激活自定义的构造函数)
2:利用MSMQ异步接收事件参数来触发remoting的事件
大约就是这样的里程,不过看上去蛮简单的,可里面用到很多MSMQ和remoting事件的知识点哦..下面是一段在remoting里面调用的dll原代码
Code
using System;
using System.Collections.Generic;
using System.Text;
using System.Messaging; //此空间必须引用Mssaging空间才能访问哦
namespace MyRemotingAndMsmq
{
/*
*关于Remoting和MSMQ系列的文章博客园里有很多
*而且介绍的又很全面,在此我也就不具体的讲解了。
*在此篇博客里我主要是针对Remoting和MSMQ结合的一些问题做个demo.
*并在重点处做个标记,本文并不全文注释,如有任何疑问请发表看法,
*欢迎大家互相学习,切磋。
*此程序具体流程很简单,如下解释
*一:利用一个Class定义个串行化类,并传给Remoting,Remoting接收MSMQ
* 里的参数,并在客户端用Remoting事件触发来接收内容。其实真实过程中
* 并不需要这么多的流程,只是本文是用来阐述这两种方法结合使用的例子,所以
* 很多此一举,呵呵。。。。
*/
public class MyContext : MarshalByRefObject //此类用来虚拟实例化事件参数类的类
{
private string name = null;
private string address = null;
private string message = null;
public MyContext(string name, string address, string message) //此构造函数将用客户端激活模式来激活
{
this.name = name;
this.address = address;
this.message = message;
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Address
{
get { return address; }
set { address = value; }
}
public string Message
{
get { return message; }
set { message = value; }
}
}
[Serializable] //此类是用来
public class MyEvent:EventArgs
{
private string name = null;
private string address = null;
private string message = null;
public MyEvent(string name, string address, string message) //此构造函数将用客户端激活模式来激活
{
this.name = name;
this.address = address;
this.message = message;
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Address
{
get { return address; }
set { address = value; }
}
public string Message
{
get { return message; }
set { message = value; }
}
}
public class MyMsmq : MarshalByRefObject //因为需要传动MyMsmq类,所以需要编组
{
public string context ="触发事件"; //因为此字段需要在类外部访问,所以需要定义public级别
string name = @".\private$\my";
MessageQueue mm = null;
public MyContext mycontext = null;
public void Shu()
{
if (MessageQueue.Exists(name))
{
mm = new MessageQueue(name);
}
else
{
mm = MessageQueue.Create(name);
}
context = mycontext.Name + "," + mycontext.Address + "," + mycontext.Message;
System.Messaging.Message m = new System.Messaging.Message();
m.Label = "异步消息发送";
m.Body=context;
mm.Send(m);
mm.ReceiveCompleted += new ReceiveCompletedEventHandler(mm_ReceiveCompleted); //定义异步接收的事件
mm.BeginReceive();
}
void mm_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
MessageQueue mq = (MessageQueue)sender;
System.Messaging.Message m = mq.EndReceive(e.AsyncResult);
m.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
context = m.Body.ToString();//改变context
mq.BeginReceive();//接收下一次事件
}
}
public class MyRemoting : MarshalByRefObject
{
public string context;
string[] contexts;
public delegate void MyDeledate(object sender, MyEvent e);
public event MyDeledate MyHandle;
MyEvent e = null;
public MyMsmq mm = null;
public void Shu()
{
if ((mm.context != "触发事件")) //这里代表MSMQ异步接收事件成功
{
contexts = mm.context.Split(new char[]{ ','});
if (contexts.Length < 2 && contexts.Length > 0)
{
e = new MyEvent(contexts[0].ToString(), contexts[1].ToString(), "自定义参数");
MyHandle(this, e);
}
if (contexts.Length > 1)
{
e = new MyEvent(contexts[0].ToString(), contexts[1].ToString(), contexts[2].ToString());
MyHandle(this, e);
}
}
}
}
}
服务器端需要创建3个远程对象,typeof(MyContext),typeof(MyMsmq),typeof(MyRemoting).代码如下using System;
using System.Collections.Generic;
using System.Text;
using System.Messaging; //此空间必须引用Mssaging空间才能访问哦
namespace MyRemotingAndMsmq
{
/*
*关于Remoting和MSMQ系列的文章博客园里有很多
*而且介绍的又很全面,在此我也就不具体的讲解了。
*在此篇博客里我主要是针对Remoting和MSMQ结合的一些问题做个demo.
*并在重点处做个标记,本文并不全文注释,如有任何疑问请发表看法,
*欢迎大家互相学习,切磋。
*此程序具体流程很简单,如下解释
*一:利用一个Class定义个串行化类,并传给Remoting,Remoting接收MSMQ
* 里的参数,并在客户端用Remoting事件触发来接收内容。其实真实过程中
* 并不需要这么多的流程,只是本文是用来阐述这两种方法结合使用的例子,所以
* 很多此一举,呵呵。。。。
*/
public class MyContext : MarshalByRefObject //此类用来虚拟实例化事件参数类的类
{
private string name = null;
private string address = null;
private string message = null;
public MyContext(string name, string address, string message) //此构造函数将用客户端激活模式来激活
{
this.name = name;
this.address = address;
this.message = message;
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Address
{
get { return address; }
set { address = value; }
}
public string Message
{
get { return message; }
set { message = value; }
}
}
[Serializable] //此类是用来
public class MyEvent:EventArgs
{
private string name = null;
private string address = null;
private string message = null;
public MyEvent(string name, string address, string message) //此构造函数将用客户端激活模式来激活
{
this.name = name;
this.address = address;
this.message = message;
}
public string Name
{
get { return name; }
set { name = value; }
}
public string Address
{
get { return address; }
set { address = value; }
}
public string Message
{
get { return message; }
set { message = value; }
}
}
public class MyMsmq : MarshalByRefObject //因为需要传动MyMsmq类,所以需要编组
{
public string context ="触发事件"; //因为此字段需要在类外部访问,所以需要定义public级别
string name = @".\private$\my";
MessageQueue mm = null;
public MyContext mycontext = null;
public void Shu()
{
if (MessageQueue.Exists(name))
{
mm = new MessageQueue(name);
}
else
{
mm = MessageQueue.Create(name);
}
context = mycontext.Name + "," + mycontext.Address + "," + mycontext.Message;
System.Messaging.Message m = new System.Messaging.Message();
m.Label = "异步消息发送";
m.Body=context;
mm.Send(m);
mm.ReceiveCompleted += new ReceiveCompletedEventHandler(mm_ReceiveCompleted); //定义异步接收的事件
mm.BeginReceive();
}
void mm_ReceiveCompleted(object sender, ReceiveCompletedEventArgs e)
{
MessageQueue mq = (MessageQueue)sender;
System.Messaging.Message m = mq.EndReceive(e.AsyncResult);
m.Formatter = new XmlMessageFormatter(new Type[] { typeof(string) });
context = m.Body.ToString();//改变context
mq.BeginReceive();//接收下一次事件
}
}
public class MyRemoting : MarshalByRefObject
{
public string context;
string[] contexts;
public delegate void MyDeledate(object sender, MyEvent e);
public event MyDeledate MyHandle;
MyEvent e = null;
public MyMsmq mm = null;
public void Shu()
{
if ((mm.context != "触发事件")) //这里代表MSMQ异步接收事件成功
{
contexts = mm.context.Split(new char[]{ ','});
if (contexts.Length < 2 && contexts.Length > 0)
{
e = new MyEvent(contexts[0].ToString(), contexts[1].ToString(), "自定义参数");
MyHandle(this, e);
}
if (contexts.Length > 1)
{
e = new MyEvent(contexts[0].ToString(), contexts[1].ToString(), contexts[2].ToString());
MyHandle(this, e);
}
}
}
}
}
Code
private void Form1_Load(object sender, EventArgs e)
{
RemotingConfiguration.ApplicationName = "remotingandmsmq"; //客户激活模式需要的URI需要在此定义
BinaryServerFormatterSinkProvider bk = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider ck = new BinaryClientFormatterSinkProvider();
bk.TypeFilterLevel = TypeFilterLevel.Full;
Dictionary<string, string> wo = new Dictionary<string, string>();
wo["port"] = "8086";
TcpChannel tcp = new TcpChannel(wo, ck, bk);//因为TcpServerChannl不支持安全性,所以用TcpChannel
ChannelServices.RegisterChannel(tcp);
RemotingConfiguration.RegisterActivatedServiceType(typeof(MyContext));
RemotingConfiguration.RegisterActivatedServiceType(typeof(MyMsmq));
RemotingConfiguration.RegisterActivatedServiceType(typeof(MyRemoting));
}
原代码下载这只是一个空的winform服务器,目的是在等待客户端调用.private void Form1_Load(object sender, EventArgs e)
{
RemotingConfiguration.ApplicationName = "remotingandmsmq"; //客户激活模式需要的URI需要在此定义
BinaryServerFormatterSinkProvider bk = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider ck = new BinaryClientFormatterSinkProvider();
bk.TypeFilterLevel = TypeFilterLevel.Full;
Dictionary<string, string> wo = new Dictionary<string, string>();
wo["port"] = "8086";
TcpChannel tcp = new TcpChannel(wo, ck, bk);//因为TcpServerChannl不支持安全性,所以用TcpChannel
ChannelServices.RegisterChannel(tcp);
RemotingConfiguration.RegisterActivatedServiceType(typeof(MyContext));
RemotingConfiguration.RegisterActivatedServiceType(typeof(MyMsmq));
RemotingConfiguration.RegisterActivatedServiceType(typeof(MyRemoting));
}
客户端调用如下
Code
private void button1_Click(object sender, EventArgs e)
{
//RemotingConfiguration.RegisterActivatedClientType(typeof(MyContext), "tcp://localhost:8086/remotingandmsmq");
object[] obj ={ new UrlAttribute("tcp://localhost:8086/remotingandmsmq") };
object[] objs = new object[3];
objs[0] = "小徐";
objs[1] = "扬州";
objs[2] = "能不能触发了";
MyContext mm = (MyContext)Activator.CreateInstance(typeof(MyContext), objs, obj);
//以上利用public static object CreateInstance(Type type, object[] args, object[] activationAttributes);
//来完成类MyContext的构造函数
RemotingConfiguration.RegisterActivatedClientType(typeof(MyMsmq), "tcp://localhost:8086/remotingandmsmq");
MyMsmq my = new MyMsmq();
my.mycontext = mm;
my.Shu();
RemotingConfiguration.RegisterActivatedClientType(typeof(MyRemoting), "tcp://localhost:8086/remotingandmsmq");
MyRemoting mym = new MyRemoting();
mym.mm = my;
//MessageBox.Show(mym.mm.context.ToString());
ClassLibrary1.Class1 c = new ClassLibrary1.Class1();
mym.MyHandle += new MyRemoting.MyDeledate(c.StatusHandler);
mym.Shu();
}
void mym_MyHandle(object sender, MyEvent e)
{
throw new Exception("The method or operation is not implemented.");
}
private void Form1_Load(object sender, EventArgs e)
{
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
Dictionary<string, string> wo = new Dictionary<string, string>();
wo["port"] = "0";
TcpChannel channel = new TcpChannel(wo, clientProvider, serverProvider);
ChannelServices.RegisterChannel(channel);
}
网站里关于这两个话题的博客很多,在这里我就不多加解释了,网友们自行查阅资料.重点地方我都做下注释了......private void button1_Click(object sender, EventArgs e)
{
//RemotingConfiguration.RegisterActivatedClientType(typeof(MyContext), "tcp://localhost:8086/remotingandmsmq");
object[] obj ={ new UrlAttribute("tcp://localhost:8086/remotingandmsmq") };
object[] objs = new object[3];
objs[0] = "小徐";
objs[1] = "扬州";
objs[2] = "能不能触发了";
MyContext mm = (MyContext)Activator.CreateInstance(typeof(MyContext), objs, obj);
//以上利用public static object CreateInstance(Type type, object[] args, object[] activationAttributes);
//来完成类MyContext的构造函数
RemotingConfiguration.RegisterActivatedClientType(typeof(MyMsmq), "tcp://localhost:8086/remotingandmsmq");
MyMsmq my = new MyMsmq();
my.mycontext = mm;
my.Shu();
RemotingConfiguration.RegisterActivatedClientType(typeof(MyRemoting), "tcp://localhost:8086/remotingandmsmq");
MyRemoting mym = new MyRemoting();
mym.mm = my;
//MessageBox.Show(mym.mm.context.ToString());
ClassLibrary1.Class1 c = new ClassLibrary1.Class1();
mym.MyHandle += new MyRemoting.MyDeledate(c.StatusHandler);
mym.Shu();
}
void mym_MyHandle(object sender, MyEvent e)
{
throw new Exception("The method or operation is not implemented.");
}
private void Form1_Load(object sender, EventArgs e)
{
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
Dictionary<string, string> wo = new Dictionary<string, string>();
wo["port"] = "0";
TcpChannel channel = new TcpChannel(wo, clientProvider, serverProvider);
ChannelServices.RegisterChannel(channel);
}