Remoting模仿QQ实现客户端,服务器端聊天功能

研究Remoting已有一段时间了,最近业务不是很忙,所以本着打发时间的关系做了这么一个小工具,献丑!。
技术含量主要是用Remoting实现客户端订阅服务器端事件和服务器端订阅客户端事件,至于客户端和客户端聊天,那就是用的这两种技术的结合体了。两个DLL原代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace YiRen.Qq.Commol
  5. {
  6.     //公共事件委托模型
  7.     public delegate void CommandHandle(string txt);
  8.     public interface IQq
  9.     {
  10.         event CommandHandle ChuFaQq;
  11.         void Send(string txt);
  12.     }
  13.     ///<summary>
  14.     ///客户端事件中间类
  15.     ///</summary>
  16.     public class CenterClass : MarshalByRefObject
  17.     {
  18.         public event CommandHandle CenterQq;
  19.         public void Fax(string txt)
  20.         {
  21.             CenterQq(txt);  //触发事件类,以此事件来更新客户端消息
  22.         }
  23.         /// <summary>
  24.         /// 继承此方法来保证事件中间客户类生命周期永远保持
  25.         /// </summary>
  26.         /// <returns></returns>
  27.         public override object InitializeLifetimeService()
  28.         {
  29.             return null;
  30.         }
  31.     }
  32.     public interface IClient
  33.     {
  34.         void ClientSend(string txt);
  35.     }
  36. }
  37. using System;
  38. using System.Collections.Generic;
  39. using System.Text;
  40. using YiRen.Qq.Commol;
  41. using System.Windows.Forms;
  42. namespace YiRen.Qq.YuanCheng
  43. {
  44.     /// <summary>
  45.     /// 远程对象类,利用此类来群发客户端消息
  46.     /// </summary>
  47.     public class ServerClass : MarshalByRefObject, IQq
  48.     {
  49.         public event CommandHandle ChuFaQq;
  50.         //检查委托链来防止客户端突然断电等远程造成系统故障
  51.         public void Send(string txt)
  52.         {
  53.             if (ChuFaQq != null)
  54.             {
  55.                 CommandHandle temp = null;
  56.                 int num = 1;  //用来记录哪个客户端出故障
  57.                 try
  58.                 {
  59.                     foreach (Delegate dele in ChuFaQq.GetInvocationList())
  60.                     {
  61.                         temp = (CommandHandle)dele;
  62.                         temp(txt);
  63.                     }
  64.                 }
  65.                 catch
  66.                 {
  67.                     MessageBox.Show("客户端" + num.ToString() + "出故障,请检查");
  68.                     num++;
  69.                 }
  70.             }
  71.         }
  72.         public override object InitializeLifetimeService()
  73.         {
  74.             return null;
  75.         }
  76.     }
  77.     public class CClient : MarshalByRefObject, IClient
  78.     {
  79.         public static event CommandHandle Client;
  80.         public void ClientSend(string txt)
  81.         {
  82.             if (Client != null)
  83.             {
  84.                 Client(txt);
  85.             }
  86.         }
  87.         public override object InitializeLifetimeService()
  88.         {
  89.             return null;
  90.         }
  91.     }
  92. }

复制代码

服务器端原代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. using YiRen.Qq.Commol;
  9. using YiRen.Qq.YuanCheng;
  10. using System.Runtime.Remoting;
  11. using System.Runtime.Remoting.Channels;
  12. using System.Runtime.Remoting.Channels.Tcp;
  13. using System.Runtime.Remoting.Channels.Http;
  14. using System.Runtime.Serialization.Formatters;
  15. using System.Collections;
  16. using System.Threading;
  17. namespace WindowsApplication1
  18. {
  19.     public partial class frmserver : Form
  20.     {
  21.         public frmserver()
  22.         {
  23.             InitializeComponent();
  24.             this.button1.Click += new EventHandler(button1_Click);
  25.         }
  26.         private ServerClass server = null;
  27.         void button1_Click(object sender, EventArgs e)
  28.         {
  29.             if (this.textBox2.Text!= string.Empty)
  30.             {
  31.                 this.textBox1.Text += this.textBox2.Text + "\r\n";
  32.                 server.Send(this.textBox2.Text.ToString());
  33.                 this.textBox2.Text = "";
  34.             }
  35.         }
  36.         private void frmserver_Load(object sender, EventArgs e)
  37.         {
  38.             BinaryServerFormatterSinkProvider ser = new BinaryServerFormatterSinkProvider();
  39.             ser.TypeFilterLevel = TypeFilterLevel.Full; //需要传送委托事件,所以必须用满格序列化
  40.             BinaryClientFormatterSinkProvider cli = new BinaryClientFormatterSinkProvider();
  41.             IDictionary wo = new Hashtable();
  42.             wo["port"] = "2000";
  43.             TcpChannel tcp = new TcpChannel(wo, cli, ser);
  44.             ChannelServices.RegisterChannel(tcp);
  45.             server = new ServerClass();
  46.             ObjRef obj =RemotingServices.Marshal(server, "Qq");
  47.             //模仿客户端群发事件的远程类
  48.             HttpChannel http = new HttpChannel(2002);
  49.             ChannelServices.RegisterChannel(http);
  50.             RemotingConfiguration.RegisterWellKnownServiceType(typeof(CClient), "Client", WellKnownObjectMode.Singleton);
  51.             CClient.Client += new CommandHandle(CClient_Client);
  52.         }
  53.         void CClient_Client(string txt)
  54.         {
  55.             this.textBox1.BeginInvoke(new MyDele(Shu), txt);
  56.             server.Send(txt.ToString());
  57.         }
  58.         delegate void MyDele(string txt);
  59.         private void Shu(string txt)
  60.         {
  61.             this.textBox1.Text += txt + "\r\n";
  62.         }
  63.     }
  64. }

复制代码

 

客户端代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Text;
  7. using System.Windows.Forms;
  8. using YiRen.Qq.Commol;
  9. using System.Runtime.Remoting;
  10. using System.Runtime.Remoting.Channels;
  11. using System.Runtime.Remoting.Channels.Tcp;
  12. using System.Runtime.Remoting.Channels.Http;
  13. using System.Runtime.Serialization.Formatters;
  14. using System.Collections;
  15. using System.Threading;
  16. namespace WindowsApplication1
  17. {
  18.     public partial class frmclient : Form
  19.     {
  20.         public frmclient()
  21.         {
  22.             InitializeComponent();
  23.         }
  24.         IQq qq = null;
  25.         IClient client = null;
  26.         delegate void MyDele(string txt);
  27.         private void Shu(string txt)
  28.         {
  29.             this.textBox1.Text += txt + "\r\n";
  30.         }
  31.         private void frmclient_Load(object sender, EventArgs e)
  32.         {
  33.             BinaryServerFormatterSinkProvider ser = new BinaryServerFormatterSinkProvider();
  34.             ser.TypeFilterLevel = TypeFilterLevel.Full; //需要传送委托事件,所以必须用满格序列化
  35.             BinaryClientFormatterSinkProvider cli = new BinaryClientFormatterSinkProvider();
  36.             IDictionary wo = new Hashtable();
  37.             wo["port"] = "0";
  38.             TcpChannel tcp = new TcpChannel(wo, cli, ser);
  39.             ChannelServices.RegisterChannel(tcp);
  40.             qq = (IQq)Activator.GetObject(typeof(IQq), "tcp://10.8.33.40:2000/Qq");
  41.             CenterClass cen = new CenterClass();
  42.             cen.CenterQq += new CommandHandle(cen_CenterQq);
  43.             qq.ChuFaQq+=new CommandHandle(cen.Fax);
  44.             ChannelServices.RegisterChannel(new HttpChannel());
  45.             client = (IClient)Activator.GetObject(typeof(IClient), "http://10.8.33.40:2002/Client");
  46.         }
  47.         void cen_CenterQq(string txt)
  48.         {
  49.             if (InvokeRequired)
  50.             {
  51.                 this.textBox1.BeginInvoke(new MyDele(Shu), txt);
  52.             }
  53.             else
  54.             {
  55.                 this.textBox1.Text += txt + "\r\n";
  56.             }
  57.         }
  58.         private void button1_Click(object sender, EventArgs e)
  59.         {
  60.             if (textBox2.Text != string.Empty)
  61.             {
  62.                 client.ClientSend(textBox2.Text);
  63.             }
  64.         }
  65.     }
  66. }
原文地址:https://www.cnblogs.com/hdl217/p/1721158.html