• 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. }
  • 相关阅读:
    Silverlight C# 游戏开发:Flyer05与什么什么进行搏斗
    Silverlight C# 游戏开发:Flyer07做一个有开始的游戏
    Silverlight C# 游戏开发:面向对象在游戏中的实例(一)
    Silverlight C# 游戏开发:面向对象在游戏中的实例(二)
    Silverlight C# 游戏开发:Flyer06小小的改进让游戏更有趣
    linux网络命令ip\route\links回顾
    Google Style的C++编码规范
    TCP/IP协议和IP组播的视频传输
    Multicast server and client in Python
    用户profile中umask码的含义详解(默认是022)
  • 原文地址:https://www.cnblogs.com/hdl217/p/1721158.html
Copyright © 2020-2023  润新知