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. 背景 在业务处理完之后,需要调用其他系统的接口,将相应的处理结果通知给对方,若是同步请求,假如调用的系统出现异常或是宕机等事件,会导致自身业务受到影响,事务会一直阻塞,数据库连接不够用等异常现象 ...
随机推荐
- UITabBarController 的配置
UITabBarController --> UITabBar Customizing Appearance backgroundImage 背景图片 selectedImageTintCol ...
- Java IO--字节-字符流转换
OutputStreamWriter和InputStreamReader 一般在操作输入输出内容的就需要使用字节或字符流,但是有些时候需要将字符流变为字节流的形式,或者将字节流变为字符流的形式,所以, ...
- JPA中的一对多双向关联与级联操作
学习Spring有两周时间了 , 个人觉得服务端主要实现的是数据关系的维护和数据结构的制定 , 以及由业务需求产生的CRUD , 只要保证对前端提供的接口稳定高效响应 , 具体的前端实现完全不关心. ...
- 算法笔记_211:第七届蓝桥杯软件类决赛部分真题(Java语言A组)
目录 1 阶乘位数 2 凑平方数 3 棋子换位 4 机器人塔 前言:以下代码仅供参考,若有错误欢迎指正哦~ 1 阶乘位数 阶乘位数 9的阶乘等于:362880 它的二进制表示为:10110001001 ...
- linux远程
apt-get install rdesktop $rdesktop -u administrator -p ****** -a 16 192.168.1.1 //都直接登陆了,
- isearch5 index,attribute和summary。
索引 isearch5 支持的索引分为:index,attribute和summary. Index指的是倒排索引,它存储了存储了从term到DocID的映射关系,形如: term-->(Doc ...
- java 泛型 精析
Created by Marydon on 1.概述 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数: 这种参数类型可以用在类.接口和方法的 ...
- 怎么将txt文件转化为html格式的文件?--极为丑陋的方式
# -*- coding: utf-8 -*- #python 27 #xiaodeng #怎么将txt文件转化为html格式的文件?--极为丑陋的方式 import os #找出所有的txt格式的文 ...
- 19、Java访问修饰符
修饰符 本类 同一个包中的类 子类 其它类 public 可以访问 可以访问 可以访问 可以访问 protected 可以访问 可以访问 可以访问 不能访问 默认 可以访问 可以访问 不能访问 不能访 ...
- HDUOJ---携程员工运动会场地问题
携程员工运动会场地问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...