三、利用事件实现服务器向客户端通信
按照之前的思路,这次利用Marshal得到的对象,去触发事件,而事件的订阅端为客户端。为了说明问题,我重新命名了一些函数和事件名,代码如下:
远程对象:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Remoting
{
public delegate void MyDelegate(string msg);
public class RemotingObject:MarshalByRefObject
{
public event MyDelegate SubscribeAtServer;//在客户端触发,在服务器订阅的事件
public event MyDelegate SubscribeAtClient;//在服务器触发,在客户端订阅的事件
//客户端触发事件
public void TriggerAtClient(string msg)
{
if (SubscribeAtServer != null)
SubscribeAtServer(msg);
}
//服务器触发事件
public void TriggerAtServer(string msg)
{
if (SubscribeAtClient != null)
SubscribeAtClient(msg);
}
//无限生命周期
public override object InitializeLifetimeService()
{
return null;
}
}
}
服务器:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using Remoting;
namespace Server
{
public partial class ServerForm : Form
{
RemotingObject marshal_obj;
public ServerForm()
{
InitializeComponent();
StartServer();
}
//开启服务器
public void StartServer()
{
//注册信道
TcpChannel tcpchannel = new TcpChannel(8080);
ChannelServices.RegisterChannel(tcpchannel,false);
//服务器获取远程对象
marshal_obj = new RemotingObject();
ObjRef objRef = RemotingServices.Marshal(marshal_obj, "url");
//服务器绑定客户端触发的事件
marshal_obj.SubscribeAtServer+=new MyDelegate(marshal_obj_SubscribeAtServer);
}
void marshal_obj_SubscribeAtServer(string msg)
{
//跨线程调用
textBox2.Invoke(new Action<string>(str => { textBox2.AppendText(str); }), msg);
}
private void 广播发送_Click(object sender, EventArgs e)
{
marshal_obj.TriggerAtServer("服务器--" + this.ServerIP() + System.Environment.NewLine + textBox1.Text + System.Environment.NewLine);
}
//获取本地ip
public string ServerIP()
{
return System.Net.Dns.GetHostAddresses(System.Net.Dns.GetHostName())[0].ToString();
}
}
}
客户端:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using Syst