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 > 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);
        }
    }
}

 

posted on 2015-10-28 20:50  HOT SUMMER  阅读(691)  评论(0编辑  收藏  举报

导航