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

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

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

1. ChatRoom (ChatRoom.cs): 服务器端真正的提供远程服务的对象,负责以服务器推(push)的方式把 Sender 发来的消息"广播"出去。

/*
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; //退出事件

public void OnMessageReceive(string Message)
{
if (MessageReceive != null)
{
//触发 Receiver 客户端 MessageReceive 事件,广播所有消息
MessageReceive(Message);
}
Console.WriteLine("Server: " + Message); //服务器消息监视
}
public void OnLogin(string User)
{
if (Login != null)
{
//触发 Receiver 客户端 Login 事件,广播 "登录" 消息
Login("System say: " + User + " Login!");
}
Console.WriteLine("Server: " + User + " Login!");
}
public void OnLogoff(string User)
{
if (Logoff != null)
{
//触发 Receiver 客户端 Logoff 事件,广播 "退出" 消息
Logoff("System say: " + User + " Logoff!");
}
Console.WriteLine("Server: " + User + " Logoff!");
}
public override object InitializeLifetimeService()
{
return null;
}
}

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):

 1<configuration>
 2<system.runtime.remoting>
 3<application>
 4<service>
 5<wellknown mode="Singleton" objecturi="ChatRoomURL" type="ChatRoom,ChatRoom"></wellknown>
 6</service>
 7<channels>
 8<channel port="8080" ref="http">
 9<!-- 注意 设置反序列化级别 -->
10<serverproviders>
11<provider ref="wsdl"></provider>
12<formatter ref="soap" typefilterlevel="Full"></formatter>
13<formatter ref="binary" typefilterlevel="Full"></formatter>
14</serverproviders>
15<clientproviders>
16<formatter ref="binary"></formatter>
17</clientproviders>
18<!-- 注意 设置反序列化级别 -->
19</channel>
20</channels>
21</application>
22</system.runtime.remoting>
23</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):

 1<configuration>
 2<system.runtime.remoting>
 3<application>
 4<client>
 5<wellknown type="ChatRoom,ChatRoom" url=" http://server:8080/ChatRoomURL "></wellknown>
 6</client>
 7<channels>
 8<channel port="0" ref="http"></channel>
 9</channels>
10</application>
11</system.runtime.remoting>
12</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!

Published At
Categories with Web编程
Tagged with
comments powered by Disqus