您的位置:首页 > 其它

Remoting异步回调,向在线用户广播消息

2015-10-28 20:50 357 查看
本文目的:向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 > 0)
tcpProperties["bindTo"] = btnBindIp.Text;

tcpProperties["timeout"] = 5;

//这个很关键,为0表示侦听所有的端口,是接收服务端回调的必要条件
tcpProperties["port"] = 0;

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", 5000);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

//处理服务端回调消息的方法
void xCallBack_ShowMsg(string str1, string str2)
{
MessageBox.Show(str1 + str2);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: