研究Remoting已有一段时间了,最近业务不是很忙,所以本着打发时间的关系做了这么一个小工具,献丑!。
技术含量主要是用Remoting实现客户端订阅服务器端事件和服务器端订阅客户端事件,至于客户端和客户端聊天,那就是用的这两种技术的结合体了。两个DLL原代码如下:
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace YiRen.Qq.Commol
- {
- //公共事件委托模型
- public delegate void CommandHandle(string txt);
- public interface IQq
- {
- event CommandHandle ChuFaQq;
- void Send(string txt);
- }
- ///<summary>
- ///客户端事件中间类
- ///</summary>
- public class CenterClass : MarshalByRefObject
- {
- public event CommandHandle CenterQq;
- public void Fax(string txt)
- {
- CenterQq(txt); //触发事件类,以此事件来更新客户端消息
- }
- /// <summary>
- /// 继承此方法来保证事件中间客户类生命周期永远保持
- /// </summary>
- /// <returns></returns>
- public override object InitializeLifetimeService()
- {
- return null;
- }
- }
- public interface IClient
- {
- void ClientSend(string txt);
- }
- }
- using System;
- using System.Collections.Generic;
- using System.Text;
- using YiRen.Qq.Commol;
- using System.Windows.Forms;
- namespace YiRen.Qq.YuanCheng
- {
- /// <summary>
- /// 远程对象类,利用此类来群发客户端消息
- /// </summary>
- public class ServerClass : MarshalByRefObject, IQq
- {
- public event CommandHandle ChuFaQq;
- //检查委托链来防止客户端突然断电等远程造成系统故障
- public void Send(string txt)
- {
- if (ChuFaQq != null)
- {
- CommandHandle temp = null;
- int num = 1; //用来记录哪个客户端出故障
- try
- {
- foreach (Delegate dele in ChuFaQq.GetInvocationList())
- {
- temp = (CommandHandle)dele;
- temp(txt);
- }
- }
- catch
- {
- MessageBox.Show("客户端" + num.ToString() + "出故障,请检查");
- num++;
- }
- }
- }
- public override object InitializeLifetimeService()
- {
- return null;
- }
- }
- public class CClient : MarshalByRefObject, IClient
- {
- public static event CommandHandle Client;
- public void ClientSend(string txt)
- {
- if (Client != null)
- {
- Client(txt);
- }
- }
- public override object InitializeLifetimeService()
- {
- return null;
- }
- }
- }
复制代码
服务器端原代码如下:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Text;
- using System.Windows.Forms;
- using YiRen.Qq.Commol;
- using YiRen.Qq.YuanCheng;
- using System.Runtime.Remoting;
- using System.Runtime.Remoting.Channels;
- using System.Runtime.Remoting.Channels.Tcp;
- using System.Runtime.Remoting.Channels.Http;
- using System.Runtime.Serialization.Formatters;
- using System.Collections;
- using System.Threading;
- namespace WindowsApplication1
- {
- public partial class frmserver : Form
- {
- public frmserver()
- {
- InitializeComponent();
- this.button1.Click += new EventHandler(button1_Click);
- }
- private ServerClass server = null;
- void button1_Click(object sender, EventArgs e)
- {
- if (this.textBox2.Text!= string.Empty)
- {
- this.textBox1.Text += this.textBox2.Text + "\r\n";
- server.Send(this.textBox2.Text.ToString());
- this.textBox2.Text = "";
- }
- }
- private void frmserver_Load(object sender, EventArgs e)
- {
- BinaryServerFormatterSinkProvider ser = new BinaryServerFormatterSinkProvider();
- ser.TypeFilterLevel = TypeFilterLevel.Full; //需要传送委托事件,所以必须用满格序列化
- BinaryClientFormatterSinkProvider cli = new BinaryClientFormatterSinkProvider();
- IDictionary wo = new Hashtable();
- wo["port"] = "2000";
- TcpChannel tcp = new TcpChannel(wo, cli, ser);
- ChannelServices.RegisterChannel(tcp);
- server = new ServerClass();
- ObjRef obj =RemotingServices.Marshal(server, "Qq");
- //模仿客户端群发事件的远程类
- HttpChannel http = new HttpChannel(2002);
- ChannelServices.RegisterChannel(http);
- RemotingConfiguration.RegisterWellKnownServiceType(typeof(CClient), "Client", WellKnownObjectMode.Singleton);
- CClient.Client += new CommandHandle(CClient_Client);
- }
- void CClient_Client(string txt)
- {
- this.textBox1.BeginInvoke(new MyDele(Shu), txt);
- server.Send(txt.ToString());
- }
- delegate void MyDele(string txt);
- private void Shu(string txt)
- {
- this.textBox1.Text += txt + "\r\n";
- }
- }
- }
复制代码
客户端代码如下:
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Text;
- using System.Windows.Forms;
- using YiRen.Qq.Commol;
- using System.Runtime.Remoting;
- using System.Runtime.Remoting.Channels;
- using System.Runtime.Remoting.Channels.Tcp;
- using System.Runtime.Remoting.Channels.Http;
- using System.Runtime.Serialization.Formatters;
- using System.Collections;
- using System.Threading;
- namespace WindowsApplication1
- {
- public partial class frmclient : Form
- {
- public frmclient()
- {
- InitializeComponent();
- }
- IQq qq = null;
- IClient client = null;
- delegate void MyDele(string txt);
- private void Shu(string txt)
- {
- this.textBox1.Text += txt + "\r\n";
- }
- private void frmclient_Load(object sender, EventArgs e)
- {
- BinaryServerFormatterSinkProvider ser = new BinaryServerFormatterSinkProvider();
- ser.TypeFilterLevel = TypeFilterLevel.Full; //需要传送委托事件,所以必须用满格序列化
- BinaryClientFormatterSinkProvider cli = new BinaryClientFormatterSinkProvider();
- IDictionary wo = new Hashtable();
- wo["port"] = "0";
- TcpChannel tcp = new TcpChannel(wo, cli, ser);
- ChannelServices.RegisterChannel(tcp);
- qq = (IQq)Activator.GetObject(typeof(IQq), "tcp://10.8.33.40:2000/Qq");
- CenterClass cen = new CenterClass();
- cen.CenterQq += new CommandHandle(cen_CenterQq);
- qq.ChuFaQq+=new CommandHandle(cen.Fax);
- ChannelServices.RegisterChannel(new HttpChannel());
- client = (IClient)Activator.GetObject(typeof(IClient), "http://10.8.33.40:2002/Client");
- }
- void cen_CenterQq(string txt)
- {
- if (InvokeRequired)
- {
- this.textBox1.BeginInvoke(new MyDele(Shu), txt);
- }
- else
- {
- this.textBox1.Text += txt + "\r\n";
- }
- }
- private void button1_Click(object sender, EventArgs e)
- {
- if (textBox2.Text != string.Empty)
- {
- client.ClientSend(textBox2.Text);
- }
- }
- }
- }