.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!

posted @ 2004-10-14 21:43  于斯人也  阅读(427)  评论(0编辑  收藏  举报