.netRemoting中客户端与服务器端对象通信,只需要服务器端注册对象,客户端获得对象代理即可使用.
下面示例是服务器端主动发消息通知客户端,相比略微复杂些,
1.服务器端首先需要生成服务器端对象,并可获得该对象的引用.
2.由于服务器端远程对象不能订阅客户端事件,所以需要一个"中间"对象做为桥梁来实现客户端订阅服务器端事件.这个"中间"对象和本来的远程对象格式写法一致.
3.委托和事件的序列化、反序列化默认是禁止的,所以我们应该将TypeFilterLevel的属性值设置为Full枚举值.
4.客户端订阅事件需要使用"中间"对象来做桥梁实现事件订阅.
5.由于客户端关闭后,服务器端对象无法得知,所以在触发服务器端事件时要使用该事件关联的委托遍历一个一个触发,并做异常处理.
远程对象Hello
代码
using System;
using System.Collections.Generic;
using System.Text;
namespace RemotingObject
{
public delegate string HelloHandler(string str);
public class Hello : MarshalByRefObject
{
public event HelloHandler HelloEvent;
private int i = 0;
public Hello()
{
Console.WriteLine("调用构造函数");
}
public string HelloWorld(string str)
{
i++;
Console.WriteLine("调用HelloWorld:" + str + i);
if (HelloEvent != null)
{
HelloHandler helloDelegate = null;
foreach (Delegate dele in HelloEvent.GetInvocationList())
{
try
{
helloDelegate = (HelloHandler)dele;
helloDelegate("调用HelloWorld:" + str + i);
}
catch
{
HelloEvent -= helloDelegate;
}
}
//HelloEvent("调用HelloWorld:" + str + i);
}
return "调用HelloWorld:" + str + i;
}
public override object InitializeLifetimeService()
{
//Remoting对象 无限生存期
return null;
}
}
public class HelloReappear : MarshalByRefObject
{
public event HelloHandler HelloEvent;
public string HelloWorld(string str)
{
Console.WriteLine("调用HelloReappear.HelloWorld:" + str);
if (HelloEvent != null)
{
HelloEvent("调用HelloWorld:" + str);
}
return "调用HelloReappear.HelloWorld:" + str;
}
public override object InitializeLifetimeService()
{
//Remoting对象 无限生存期
return null;
}
}
}
using System.Collections.Generic;
using System.Text;
namespace RemotingObject
{
public delegate string HelloHandler(string str);
public class Hello : MarshalByRefObject
{
public event HelloHandler HelloEvent;
private int i = 0;
public Hello()
{
Console.WriteLine("调用构造函数");
}
public string HelloWorld(string str)
{
i++;
Console.WriteLine("调用HelloWorld:" + str + i);
if (HelloEvent != null)
{
HelloHandler helloDelegate = null;
foreach (Delegate dele in HelloEvent.GetInvocationList())
{
try
{
helloDelegate = (HelloHandler)dele;
helloDelegate("调用HelloWorld:" + str + i);
}
catch
{
HelloEvent -= helloDelegate;
}
}
//HelloEvent("调用HelloWorld:" + str + i);
}
return "调用HelloWorld:" + str + i;
}
public override object InitializeLifetimeService()
{
//Remoting对象 无限生存期
return null;
}
}
public class HelloReappear : MarshalByRefObject
{
public event HelloHandler HelloEvent;
public string HelloWorld(string str)
{
Console.WriteLine("调用HelloReappear.HelloWorld:" + str);
if (HelloEvent != null)
{
HelloEvent("调用HelloWorld:" + str);
}
return "调用HelloReappear.HelloWorld:" + str;
}
public override object InitializeLifetimeService()
{
//Remoting对象 无限生存期
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 System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using RemotingObject;
using System.Runtime.Serialization.Formatters;
using System.Collections;
namespace Server
{
public partial class FrmServer : Form
{
private Hello objHello;
public FrmServer()
{
InitializeComponent();
}
private void btnCreate_Click(object sender, EventArgs e)
{
BinaryServerFormatterSinkProvider sfsp = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider cfsp = new BinaryClientFormatterSinkProvider();
sfsp.TypeFilterLevel = TypeFilterLevel.Full;
Hashtable props = new Hashtable();
props["name"] = "name1";
props["port"] = 7777;
//TcpServerChannel serverChannel = new TcpServerChannel(props,sfsp);
TcpChannel serverChannel = new TcpChannel(props, cfsp, sfsp);
ChannelServices.RegisterChannel(serverChannel, false);
//RemotingConfiguration.RegisterWellKnownServiceType(typeof(Hello), "Hello", WellKnownObjectMode.Singleton);
objHello = new Hello();
RemotingServices.Marshal(objHello,"Hello");
}
private void FrmServer_FormClosing(object sender, FormClosingEventArgs e)
{
RemotingServices.Disconnect(objHello);
IChannel[] channels = ChannelServices.RegisteredChannels;
foreach (IChannel channel in channels)
{
((TcpChannel)channel).StopListening(null);
ChannelServices.UnregisterChannel(((TcpChannel)channel));
}
}
private void btnSend_Click(object sender, EventArgs e)
{
objHello.HelloWorld(textBox1.Text);
}
}
}
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;
using RemotingObject;
using System.Runtime.Serialization.Formatters;
using System.Collections;
namespace Server
{
public partial class FrmServer : Form
{
private Hello objHello;
public FrmServer()
{
InitializeComponent();
}
private void btnCreate_Click(object sender, EventArgs e)
{
BinaryServerFormatterSinkProvider sfsp = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider cfsp = new BinaryClientFormatterSinkProvider();
sfsp.TypeFilterLevel = TypeFilterLevel.Full;
Hashtable props = new Hashtable();
props["name"] = "name1";
props["port"] = 7777;
//TcpServerChannel serverChannel = new TcpServerChannel(props,sfsp);
TcpChannel serverChannel = new TcpChannel(props, cfsp, sfsp);
ChannelServices.RegisterChannel(serverChannel, false);
//RemotingConfiguration.RegisterWellKnownServiceType(typeof(Hello), "Hello", WellKnownObjectMode.Singleton);
objHello = new Hello();
RemotingServices.Marshal(objHello,"Hello");
}
private void FrmServer_FormClosing(object sender, FormClosingEventArgs e)
{
RemotingServices.Disconnect(objHello);
IChannel[] channels = ChannelServices.RegisteredChannels;
foreach (IChannel channel in channels)
{
((TcpChannel)channel).StopListening(null);
ChannelServices.UnregisterChannel(((TcpChannel)channel));
}
}
private void btnSend_Click(object sender, EventArgs e)
{
objHello.HelloWorld(textBox1.Text);
}
}
}
客户端代码
代码
using System;
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;
using RemotingObject;
using System.Runtime.Serialization.Formatters;
using System.Collections;
namespace Client
{
public partial class FrmClient : Form
{
private delegate void InvokeCallback(string msg);
private Hello objHello;
public FrmClient()
{
InitializeComponent();
}
private void btnGetRemoteObject_Click(object sender, EventArgs e)
{
BinaryServerFormatterSinkProvider sfsp = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider cfsp = new BinaryClientFormatterSinkProvider();
Hashtable props = new Hashtable();
props["name"] = "name1";
props["port"] = 0;
//TcpClientChannel clientChannel = new TcpClientChannel(props, null);
TcpChannel clientChannel = new TcpChannel(props,cfsp,sfsp);
//TcpChannel clientChannel = new TcpChannel(props,null,null);
ChannelServices.RegisterChannel(clientChannel, false);
objHello = (Hello)Activator.GetObject(typeof(Hello), "tcp://192.168.1.10:7777/Hello");
if (objHello == null)
{
Console.WriteLine("获取远程对象失败");
return;
}
HelloReappear objHelloReappear = new HelloReappear();
objHello.HelloEvent += new HelloHandler(objHelloReappear.HelloWorld);
objHelloReappear.HelloEvent += new HelloHandler(objHelloReappear_HelloEvent);
//Console.WriteLine(objHello.HelloWorld("客户端已创建对象"));
}
private string objHelloReappear_HelloEvent(string str)
{
Console.WriteLine("客户端事件触发:" + str);
str = "客户端事件触发:" + str;
if (textBox1.InvokeRequired)
{
InvokeCallback callback = new InvokeCallback(setMessage);
textBox1.Invoke(callback, new object[] { str });
}
else
{
textBox1.Text += str + "\r\n";
}
return "客户端事件触发:" + str;
}
private void setMessage(string str)
{
textBox1.Text += str + "\r\n";
}
private void FrmClient_FormClosing(object sender, FormClosingEventArgs e)
{
IChannel[] channels = ChannelServices.RegisteredChannels;
foreach (IChannel channel in channels)
{
((TcpChannel)channel).StopListening(null);
ChannelServices.UnregisterChannel(((TcpChannel)channel));
}
}
}
}
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;
using RemotingObject;
using System.Runtime.Serialization.Formatters;
using System.Collections;
namespace Client
{
public partial class FrmClient : Form
{
private delegate void InvokeCallback(string msg);
private Hello objHello;
public FrmClient()
{
InitializeComponent();
}
private void btnGetRemoteObject_Click(object sender, EventArgs e)
{
BinaryServerFormatterSinkProvider sfsp = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider cfsp = new BinaryClientFormatterSinkProvider();
Hashtable props = new Hashtable();
props["name"] = "name1";
props["port"] = 0;
//TcpClientChannel clientChannel = new TcpClientChannel(props, null);
TcpChannel clientChannel = new TcpChannel(props,cfsp,sfsp);
//TcpChannel clientChannel = new TcpChannel(props,null,null);
ChannelServices.RegisterChannel(clientChannel, false);
objHello = (Hello)Activator.GetObject(typeof(Hello), "tcp://192.168.1.10:7777/Hello");
if (objHello == null)
{
Console.WriteLine("获取远程对象失败");
return;
}
HelloReappear objHelloReappear = new HelloReappear();
objHello.HelloEvent += new HelloHandler(objHelloReappear.HelloWorld);
objHelloReappear.HelloEvent += new HelloHandler(objHelloReappear_HelloEvent);
//Console.WriteLine(objHello.HelloWorld("客户端已创建对象"));
}
private string objHelloReappear_HelloEvent(string str)
{
Console.WriteLine("客户端事件触发:" + str);
str = "客户端事件触发:" + str;
if (textBox1.InvokeRequired)
{
InvokeCallback callback = new InvokeCallback(setMessage);
textBox1.Invoke(callback, new object[] { str });
}
else
{
textBox1.Text += str + "\r\n";
}
return "客户端事件触发:" + str;
}
private void setMessage(string str)
{
textBox1.Text += str + "\r\n";
}
private void FrmClient_FormClosing(object sender, FormClosingEventArgs e)
{
IChannel[] channels = ChannelServices.RegisteredChannels;
foreach (IChannel channel in channels)
{
((TcpChannel)channel).StopListening(null);
ChannelServices.UnregisterChannel(((TcpChannel)channel));
}
}
}
}