zoukankan      html  css  js  c++  java
  • .Net Remoting 实现简易的"命令行控制台"聊天室

    .Net Remoting 实现简易的控制台命令行聊天室

    本套程序由四个主要的对象组成:


    1. ChatRoom  (ChatRoom.cs): 服务器端真正的提供远程服务的对象,负责以服务器推(push)的方式把 Sender 发来的消息"广播"出去。
     2004-12-29 修订,使 Server Side 程序更加健壮!
    /*
      csc.exe ChatRoom.cs /t:library ChatRoom.dll
    */

    using System;
    using System.Runtime.Remoting;

    //[Serializable]
    public class ChatRoom : MarshalByRefObject
    {
     //定义了 1 个名为 "ChatRoomEventHandler 的事件处理委托" 及其参数格式签名
     public delegate void ChatRoomEventHandler(string s);

     //定义了 3 个 "ChatRoomEventHandler 委托类型" 的事件及远程回调函数
     public event ChatRoomEventHandler MessageReceive; //消息接收事件
     public event ChatRoomEventHandler Login; //登录事件
     public event ChatRoomEventHandler Logoff; //退出事件

    // [System.Runtime.Remoting.Messaging.OneWay]
     public void OnMessageReceive(string Message)
     {
      if (MessageReceive != null)
      {
       //触发 Receiver 客户端 MessageReceive 事件,广播所有消息

       RaiseEvents(ref MessageReceive,ref Message);
       //MessageReceive(Message);
      }
      Console.WriteLine("Server: " + Message); //服务器消息监视
     }

    // [System.Runtime.Remoting.Messaging.OneWay]
     public void OnLogin(string User)
     {
      string s = "System say: " + User + " Login!";
      if (Login != null)
      {
       //触发 Receiver 客户端 Login 事件,广播 "登录" 消息
       RaiseEvents(ref Login,ref s);
       //Login("System say: " + User + " Login!");
      }
      Console.WriteLine("Server: " + s);
     }

    // [System.Runtime.Remoting.Messaging.OneWay]
     public void OnLogoff(string User)
     {
      string s = "System say: " + User + " Logoff!";
      if (Logoff != null)
      {
       //触发 Receiver 客户端 Logoff 事件,广播 "退出" 消息
       //Logoff("System say: " + User + " Logoff!");
       RaiseEvents(ref Logoff,ref s);
      }
      Console.WriteLine("Server: " + s);
     }
     public override object InitializeLifetimeService()
     {
      return null;
     }
    // 参阅 Ingo Rammer《Advanced .NET Remoting》
     public void RaiseEvents(ref ChatRoomEventHandler e,ref string Message)
     {
      ChatRoomEventHandler creh = null;
      int i = 1;
      Delegate[] D = e.GetInvocationList();
      foreach (Delegate d in D)
      {
       try
       {
        creh = (ChatRoomEventHandler) d;
        creh(Message);
       }
       catch
       {
        Message = "第 " + i.ToString() + " 个订阅者发生错误,系统取消其事件订阅!";
        e -= creh;
       }
       i ++;
      }
     }
    }


    2. Server: 服务器。远程服务对象的宿主程序而已。
    /*
      csc.exe Server.cs
    */

    using System;
    using System.Runtime.Remoting;

    class Server
    {
     public static void Main(string[] Args)
     {
      RemotingConfiguration.Configure("s.config");
      Console.WriteLine("Server .... , Press Enter key to exit.");
      Console.ReadLine();
     }
    }

    下面是 Server 的配置文件 (s.config):
    <configuration>
     <system.runtime.remoting>
      <application>
       <service>
        <wellknown mode="Singleton" type="ChatRoom,ChatRoom" objectUri="ChatRoomURL" />
       </service>
       <channels>
        <channel ref="http" port="8080">
         <serverProviders>
          <provider ref="wsdl" />
          <formatter ref="soap" typeFilterLevel="Full" />
          <formatter ref="binary" typeFilterLevel="Full" />
         </serverProviders>
         <clientProviders>
          <formatter ref="binary" />
         </clientProviders>
        </channel>
       </channels>
      </application>
     </system.runtime.remoting>
    </configuration>


    3. Sender (Sender.cs): 客户端消息发送器对象,负责把"广播"的消息发送到远程服务对象。
    /*
      csc.exe /r:ChatRoom.dll Sender.cs
    */

    using System;
    using System.Timers;
    using System.Runtime.Remoting;
    using System.Runtime.Remoting.Channels;
    using System.Runtime.Remoting.Channels.Http;

    class Sender
    {
     ChatRoom x;
     public static void Main(string[] Args)
     {
      Sender y = new Sender();
      y.Run();
     }
     string User;
     public void Run()
     {
      Console.WriteLine("Messages Sender ... ,Press 'q' to exit Chatting.");
    //  以配置方式获取远程服务对象实例
    //  RemotingConfiguration.Configure("c.config");
    //  x = new ChatRoom();

      //以编程方式获取远程服务对象实例
      System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(new System.Runtime.Remoting.Channels.Http.HttpChannel());
      x = (ChatRoom) System.Activator.GetObject(typeof(ChatRoom),"http://server:8080/ChatRoomURL");

    //先登录
      Console.WriteLine("make a name then Login Please:"); 
      User = Console.ReadLine();

      //调用此远程方法,通知服务器触发 Receiver 客户端 Login 事件,广播 "登录" 消息
      x.OnLogin(User);

      Console.WriteLine("welcome " + User + ",Send your Message Please:");

      string s; //存储键入的消息文字

      while ((s=Console.ReadLine()) != "q") //如果键入 q 退出循环
      {
       //调用此远程方法,通知服务器触发 Receiver 客户端 MessageReceive 事件,广播你所键入的消息
       x.OnMessageReceive(User + " say: " + s);
      }

      //调用此远程方法,通知服务器触发 Receiver 客户端 Logoff 事件,广播 "退出" 消息
      x.OnLogoff(User);
      Console.WriteLine("bye bye " + User);
     }
    }


    4. Receiver (Receiver.cs): 客户端消息接收器对象,负责"自动"接收远程服务对象从 Sender 接收并转发"广播"的所有消息。
    /*
      csc.exe /r:ChatRoom.dll Receiver.cs
    */

    using System;
    using System.Runtime.Remoting;
    using System.Runtime.Remoting.Channels;
    using System.Runtime.Remoting.Channels.Http;

    //Receiver 对象必须要继承 MarshalByRefObject,由于相对于服务器, Receiver 对象 也要为其提供远程服务。
    class Receiver : MarshalByRefObject
    {
     ChatRoom x;

     public static void Main()
     {
      Receiver y = new Receiver();
      y.Run();
     }
     
     public void Run()
     {
      RemotingConfiguration.Configure("c.config"); //相当于后期运行时绑定
      x = new ChatRoom();
      //向远程服务对象"注册"本地回调函数 this.Message_Receive1
      x.MessageReceive += new ChatRoom.ChatRoomEventHandler(this.Message_Receive1);
      //Login Logoff 与 MessageReceive 签名一样
      x.Login += new ChatRoom.ChatRoomEventHandler(this.Message_Receive1);
      x.Logoff += new ChatRoom.ChatRoomEventHandler(this.Message_Receive1);

      Console.WriteLine("Messages Receiver ... ,Press Enter key to exit.");

      Console.ReadLine(); //退出关闭接收器

      //千万不要忘记结束时取消委托关系
      x.MessageReceive -= new ChatRoom.ChatRoomEventHandler(this.Message_Receive1);
      x.Login -= new ChatRoom.ChatRoomEventHandler(this.Message_Receive1);
      x.Logoff -= new ChatRoom.ChatRoomEventHandler(this.Message_Receive1);
     }

     //这个就是被服务器端远程回调的函数
     public void Message_Receive1(string s)
     {
      Console.WriteLine(s);//在本地显示接收的广播消息
     }

     public override object InitializeLifetimeService()
     {
      return null;
     }
    }

    下面是 Sender 和 Receiver 的配置文件 (c.config):
    <configuration>
     <system.runtime.remoting>
      <application>
       <client>
        <wellknown type="ChatRoom,ChatRoom" url="http://server:8080/ChatRoomURL" />
       </client>
       <channels>
        <channel ref="http" port="0" />
       </channels>
      </application>
     </system.runtime.remoting>
    </configuration>


    编译:

    csc /t:library chatroom.cs
    csc /r:chatroom.dll server.cs
    csc /r:chatroom.dll sender.cs
    csc /r:chatroom.dll receiver.cs


    用法:
    运行顺序:

    1.先运行 服务器端:
    Server.exe
    2.再运行 客户端:
    Sender.exe 用于登录、发消息、退出
    Receiver.exe 仅用与接收并显示消息

    注意: 不要通过关闭命令行控制台窗口退出程序!

      Server.exe : Press "Enter" key to exit!

      Sender.exe : Press "q" key to exit!
    Receiver.exe : Press "Enter" key to exit!

  • 相关阅读:
    数据库学习笔记5---MySQL字符串函数、日期时间函数
    关于hibernate的AnnotationConfiguration的问题
    浅谈Java web 中request的setAttribute()用法
    JAVA常见面试题之Forward和Redirect的区别
    JSP页面中<%!%>与<%%>与<%=%>
    Servlet的生命周期
    JavaEE学习路线图
    java web项目WEB-INF与META-INF的作用
    iOS-申请邓白氏编码的超详细流程介绍
    从高版本JDK换成低版本JDK报错
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/2485764.html
Copyright © 2011-2022 走看看