zoukankan      html  css  js  c++  java
  • 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);
            }
        }
    }
  • 相关阅读:
    Unity--------------------万向锁的概念
    unity--------prefab嵌套prefab
    ListView嵌套 EditText的光标不显示
    maven clean package 时出现Failed to read artifact descriptor for的问题解决
    maven打包之后为什么class文件中没有注释了?
    Maven中maven-source-plugin,maven-javadoc-plugin插件的使用
    c3p0三种配置方式(automaticTestTable)
    db2设置共享内存
    解决Tomcat数据连接池无法释放
    DB2死锁的解决办法
  • 原文地址:https://www.cnblogs.com/wangchuang/p/4918602.html
Copyright © 2011-2022 走看看