本文目的:向Remoting在线客户端广播消息。
使用的主要技术:异步,回调,广播。
实现过程:
定义远程实例
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting.Messaging; namespace RemoteObject
{
//定义委托,显示回调消息
public delegate void ShowCallBackMsg(string str1,string str2); //在客户端生成的远程实例,供服务端调用回调
public class OnLineCallBack:MarshalByRefObject
{
//客户端实现委托的方法
public ShowCallBackMsg ShowMsg; //供服务端调用回调
public void CallBack(string str1, string str2)
{
if (ShowMsg != null)
{
ShowMsg.Invoke(str1, str2);
}
} } //在服务端运行的远程实例
public class RemoteObject:MarshalByRefObject
{
//静态变量 记录每个客户端生成供回调的远程实例
public static List<OnLineCallBack> ListOnline = new List<OnLineCallBack>(); public RemoteObject()
{
} //添加用户端生成供回调的远程实例
public void AddOnlineCallBack(OnLineCallBack xCallBack)
{
ListOnline.Add(xCallBack);
} //使用OneWay,异步执行,客户端发出执行命令,即不再等待返回,交由服务端回调处理
[System.Runtime.Remoting.Messaging.OneWay]
public void DoSomething(string str1, string str2, int isleep)
{
//为看效果,等待时长
System.Threading.Thread.Sleep(isleep); //将所有登记的在线远程实例执行回调,广播消息
foreach (OnLineCallBack xCallBack in ListOnline)
{
xCallBack.CallBack(str1, str2);
}
} }
}
服务端:
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels ;
using System.Runtime.Remoting.Channels.Tcp ; namespace RemoteServer
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} TcpChannel chan1; private void button1_Click(object sender, EventArgs e)
{
//启动服务端
try
{
IDictionary tcpProperties = new Hashtable(); tcpProperties["name"] = "RemoteTest"; //指定服务端口
tcpProperties["port"] = int.Parse(textBox1.Text); BinaryClientFormatterSinkProvider tcpClientSinkProvider = new BinaryClientFormatterSinkProvider();
BinaryServerFormatterSinkProvider tcpServerSinkProvider = new BinaryServerFormatterSinkProvider();
tcpServerSinkProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full; chan1 = new TcpChannel(tcpProperties, tcpClientSinkProvider, tcpServerSinkProvider); ChannelServices.RegisterChannel(chan1); RemotingConfiguration.RegisterWellKnownServiceType(
typeof(RemoteObject.RemoteObject), "RemoteTest", WellKnownObjectMode.Singleton); MessageBox.Show("Start Success!"); button1.Enabled = false ;
button2.Enabled = true ; }
catch (Exception ex)
{
MessageBox.Show(ex.Message);
} } //停止服务端
private void button2_Click(object sender, EventArgs e)
{
try
{
if (chan1 != null)
{
ChannelServices.UnregisterChannel(chan1);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
} button1.Enabled = true;
button2.Enabled = false;
} }
}
客户端
using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Services;
using System.Runtime.Remoting.Channels.Tcp; namespace RemoteClient
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} TcpChannel chan1 = null;
RemoteObject.RemoteObject obj1 = null;
private void btnConnect_Click(object sender, EventArgs e)
{
//连接服务端
try
{
IDictionary tcpProperties = new Hashtable(); BinaryClientFormatterSinkProvider tcpClientSinkProvider = new BinaryClientFormatterSinkProvider();
BinaryServerFormatterSinkProvider tcpServerSinkProvider = new BinaryServerFormatterSinkProvider();
tcpServerSinkProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full; //为防止客户端有多个网卡IP,指定使用可以与服务端通信的IP
if (btnBindIp.Text.Trim().Length > )
tcpProperties["bindTo"] = btnBindIp.Text; tcpProperties["timeout"] = ; //这个很关键,为0表示侦听所有的端口,是接收服务端回调的必要条件
tcpProperties["port"] = ; chan1 = new TcpChannel(tcpProperties, tcpClientSinkProvider, tcpServerSinkProvider); //注册通信管道
ChannelServices.RegisterChannel(chan1);
obj1 = (RemoteObject.RemoteObject)Activator.GetObject(
typeof(RemoteObject.RemoteObject),
"tcp://" + txtSrvIP.Text + ":" + txtSrvPort.Text + "/RemoteTest"); //生成供服务端回调的客户端远程实例
RemoteObject.OnLineCallBack xCallBack = new RemoteObject.OnLineCallBack();
//指定接收处理服务端回调的方法
xCallBack.ShowMsg = new RemoteObject.ShowCallBackMsg(xCallBack_ShowMsg);
//调用服务端远程方法AddOnlineCallBack,记录客户端远程实例
obj1.AddOnlineCallBack(xCallBack); btnConnect.Enabled = false;
btnInvoke.Enabled = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message); btnConnect.Enabled = true;
btnInvoke.Enabled = false;
}
} private void btnBreak_Click(object sender, EventArgs e)
{
try
{
//断开连接
ChannelServices.UnregisterChannel(chan1);
obj1 = null;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
} btnConnect.Enabled = true;
btnBreak.Enabled = false; } private void btnInvoke_Click(object sender, EventArgs e)
{
try
{
//调用服务端RemoteObject的远程方法(其方法是OneWay的异步模式)
obj1.DoSomething("AAA", "BBB", );
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
} //处理服务端回调消息的方法
void xCallBack_ShowMsg(string str1, string str2)
{
MessageBox.Show(str1 + str2);
}
}
}