Remoting异步回调,向在线用户广播消息
本文目的:向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异步回调,向在线用户广播消息的更多相关文章
- linux上给其他在线用户发送信息(wall, write, talk, mesg)
linux上给其他在线用户发送信息(wall, write, talk, mesg) 2018-01-05 lonskyMR 转自 恶之一眉 修改 微信分享: 设置登录提示 /et ...
- 协程 & 用户级(内核级)线程 & 切换开销 & 协程与异步回调的差异
今天先是看到多线程级别的内容,然后又看到协程的内容. 基本的领会是,协程是对异步回调方式的一种变换,同样是在一个线程内,协程通过主动放弃时间片交由其他协程执行来协作,故名协程. 而协程很早就有了,那时 ...
- Linux--网络通信命令(给其它用户发送广播消息)
1.命令名称:write 执行权限:所有用户 功能描述:向另外一个用户发送信息,以CTRL+D作为结束 语法:write <用户名>root向luxh用户发送信息[root@localh ...
- 委托(delegate)的三种调用方式:同步调用,异步调用,异步回调(转载)
下面为即将被调用的方法: public delegate int AddHandler(int a,int b); public class 加法类 { public static int Add(i ...
- C#“同步调用”、“异步调用”、“异步回调”
本文将主要通过“同步调用”.“异步调用”.“异步回调”三个示例来讲解在用委托执行同一个“加法类”的时候的的区别和利弊. 首先,通过代码定义一个委托和下面三个示例将要调用的方法: ); //模拟该方法运 ...
- 网络编程(学习整理)---3--(Udp)FeiQ实现广播消息群发
1.广播群发消息: 这里使用的任然是UDP协议,使用方法还是比较简单的! 我就记录一下需要注意的一些地方(笔记): (1)这里是在局域网内,借用FeiQ聊天软件,编写一段程序,实现对局域网内的每一个登 ...
- C# 委托的三种调用示例(同步调用 异步调用 异步回调)
首先,通过代码定义一个委托和下面三个示例将要调用的方法: 复制代码 代码如下: public delegate int AddHandler(int a,int b); public class ...
- springboot整合websocket实现一对一消息推送和广播消息推送
maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- Java按时间梯度实现异步回调接口
1. 背景 在业务处理完之后,需要调用其他系统的接口,将相应的处理结果通知给对方,若是同步请求,假如调用的系统出现异常或是宕机等事件,会导致自身业务受到影响,事务会一直阻塞,数据库连接不够用等异常现象 ...
随机推荐
- 【转载】Remote System Explorer Operation总是运行后台服务,卡死eclipse解决办法
原来是eclipse后台进程在远程操作,就是右下角显示的“Remote System Explorer Operation”.折腾了半天,在Stack Overflow找到答案(源地址).把解决方案翻 ...
- ZH奶酪:C语言中malloc()和free()函数解析
1.malloc()和free()的基本介绍 (1)函数原型及说明 void *malloc(long NumBytes) 该函数分配了NumBytes个字节,并返回了指向这块内存的指针.如果分配失败 ...
- UISlider设置按钮透明
UISlider *aslider = [[UISlider alloc]initWithFrame:kCR(, , , )]; [aslider setValue:0.5]; [aslider se ...
- TP3.2 APP_DEBUG=false关闭调试后访问不了。页面错误!请稍后再试~
在APP_DEBUG=true时是没问题的,在APP_DEBUG=false时才会出现找不到模板的问题. 经过排查可能是模板文件找不到问题,之前是这么写的. 改为这个就好了. ----------- ...
- java之八大排序
的关系: 1.直接插入排序 (1)基本思想:在要排序的一组数中,假设前面(n-1)[n>=2] 个数已经是排 好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数 也是排好顺序的.如此反 ...
- 安装itunes时提示不能删除旧版本的apple应用程序支持
下载我 选择需要卸载清理的程序(所有与Apple有关的) ok
- ubuntu下的fdisk用法
Linux下的fdisk功能是极其强大的,用它可以划分出最复杂的分区,下面简要介绍一下它的用法: 对 于IDE硬盘,每块盘有一个设备名:对应于主板的四个IDE接口,设备名依次为:/dev/hda,/d ...
- MYSQL在Win下免安装zip
mysql对于Win测试简单zip安装即可了解my.in配置文件的妙处(show variables),本地搭建mysql服务测试引擎! 01.下载 https://dev.mysql.com/dow ...
- linux下使用speedtest测速
Speedtest测试网络上传/下载速度还是挺不错的,windows下非常方便.Linux下也可以很方便的使用命令行speedtest来测试.speedtest是一个用Python编写的轻量级Linu ...
- PHP-Ajax跨域解决方案
1.先了解下Ajax跨域问题: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "ht ...