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

来源:互联网 发布:paparecipeq正品软件 编辑:程序博客网 时间:2024/05/11 09:05

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