技术含量主要是用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";
}
}
}