本文目的:向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);
}
}
}

Remoting异步回调,向在线用户广播消息的更多相关文章

  1. linux上给其他在线用户发送信息(wall, write, talk, mesg)

        linux上给其他在线用户发送信息(wall, write, talk, mesg)   2018-01-05 lonskyMR 转自 恶之一眉 修改 微信分享: 设置登录提示     /et ...

  2. 协程 & 用户级(内核级)线程 & 切换开销 & 协程与异步回调的差异

    今天先是看到多线程级别的内容,然后又看到协程的内容. 基本的领会是,协程是对异步回调方式的一种变换,同样是在一个线程内,协程通过主动放弃时间片交由其他协程执行来协作,故名协程. 而协程很早就有了,那时 ...

  3. Linux--网络通信命令(给其它用户发送广播消息)

    1.命令名称:write 执行权限:所有用户  功能描述:向另外一个用户发送信息,以CTRL+D作为结束 语法:write <用户名>root向luxh用户发送信息[root@localh ...

  4. 委托(delegate)的三种调用方式:同步调用,异步调用,异步回调(转载)

    下面为即将被调用的方法: public delegate int AddHandler(int a,int b); public class 加法类 { public static int Add(i ...

  5. C#“同步调用”、“异步调用”、“异步回调”

    本文将主要通过“同步调用”.“异步调用”.“异步回调”三个示例来讲解在用委托执行同一个“加法类”的时候的的区别和利弊. 首先,通过代码定义一个委托和下面三个示例将要调用的方法: ); //模拟该方法运 ...

  6. 网络编程(学习整理)---3--(Udp)FeiQ实现广播消息群发

    1.广播群发消息: 这里使用的任然是UDP协议,使用方法还是比较简单的! 我就记录一下需要注意的一些地方(笔记): (1)这里是在局域网内,借用FeiQ聊天软件,编写一段程序,实现对局域网内的每一个登 ...

  7. C# 委托的三种调用示例(同步调用 异步调用 异步回调)

    首先,通过代码定义一个委托和下面三个示例将要调用的方法: 复制代码 代码如下: public delegate int AddHandler(int a,int b);    public class ...

  8. springboot整合websocket实现一对一消息推送和广播消息推送

    maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  9. Java按时间梯度实现异步回调接口

    1. 背景 在业务处理完之后,需要调用其他系统的接口,将相应的处理结果通知给对方,若是同步请求,假如调用的系统出现异常或是宕机等事件,会导致自身业务受到影响,事务会一直阻塞,数据库连接不够用等异常现象 ...

随机推荐

  1. Windows 之 防火墙

          对于只使用浏览.电子邮件等系统自带的网络应用程序,Windows防火墙(firewall)根本不会产生影响.也就是说,用IE.OutlookExpress等系统自带的程序进行网络连接,防火 ...

  2. UIFont可用字体

    label.font = [UIFont fontWithName:@"Arial-BoldItalicMT" size:24]; 字体名如下: Font Family: Amer ...

  3. wepy - 与原生有什么不同(事件更改)

    对于repeat,详情见官方文档 <style lang="less"> .userinfo { display: flex; flex-direction: colu ...

  4. 动态IP或无公网IP时外网訪问内网ORACLE数据库

    ORACLE数据库是应用最多的一个数据库.一般项目应用.将ORACLE部署在内网,内网调用,及运维都仅仅能是内网完毕. 假设ORACLE主机或所在局域网没有固定公网IP,又想在外网对ORACLE进行訪 ...

  5. SQL左连接右连接

    假设有A,B两个表.     表A记录如下:   aID     aNum   1     a20050111   2     a20050112   3     a20050113   4      ...

  6. Java程序猿学习C++之数组和动态数组

    数组: #include <iostream> using namespace std; //模板函数 template <class T> void dump(T val) ...

  7. HDU 5402 Travelling Salesman Problem(棋盘染色 构造 多校啊)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5402 Problem Description Teacher Mai is in a maze wit ...

  8. PHP微信公众平台

    微信公众平台客户中心微信公众平台开发文档微信公众平台自定义菜单微信公众平台开发(一) 配置接口微信公众平台开发(二) 微信公众平台示例代码分析微信公众平台开发(三) 订阅事件(subscribe)处理 ...

  9. PHP原生实现,校验微信公众号||小程序服务器地址

    1.原生的.php文件:  test.php <?php header('Content-type:text'); define("TOKEN", "weixin& ...

  10. mysql中字符集和排序规则说明

    数据库需要适应各种语言和字符就需要支持不同的字符集(Character Set),每种字符集也有各自的排序规则(Collation). 一.字符集 字符集,即用于定义字符在数据库中的编码的集合. 常见 ...