用c#写的基于remoting写的分布式会话中一个奇怪的问题。远程类中有一个事件是专门用来处理消息的,有一个抽象类,这个事件要调用这个方法。客户端中重写这个方法。但是客户端一放送消息鼠标就转圈圈,应该是”死“了,其他客户端又可以显示这个客户端发送的消息,但是这个客户端就不能再发送消息了
远程类代码:
using System;
using System.Runtime.Remoting;
using System.Collections;
[Serializable]
public class SubmitEventArgs : EventArgs
{
private string _content = null;
private string _alias = null;
public SubmitEventArgs( string addressor,string address)
{
this._content = address;
this._alias = addressor;
}
//属性值Address存放发言的内容
public string Address
{
get
{
return _content;
}
}
//属性值Addressor存放发言人的别名
public string Addressor
{
get
{
return _alias;
}
}
}
//声明一个代理
public delegate void SubmissionEventHandler(object sender, SubmitEventArgs submitArgs);
// 定义远程处理类ChatCoordinator。我们所定义的远程类ChatCoordinator的
//主要功能就是定义并触发Submission事件,同时为订阅此事件的客户端传递信息
public class ChatCoordinator : MarshalByRefObject
{
public ChatCoordinator()
{
Console.WriteLine("ChatCoordinator has benn created.");
}
//通过对函数InitializeLifetimeService编写,忽略默认的对象租用行为,这样在主机应用程
//序域运行时始终将对象保存在内存中
public override object InitializeLifetimeService()
{
return null;
}
public string CurrentTime()
{
return DateTime.Now.ToLongTimeString()+"Hello";
}
// 声明Submission事件,客户端将会订阅此事件
public event SubmissionEventHandler Submission;
//定义Submit处理程序,在客户端将会远程调用此函数。我们所定义的远程
//类ChatCoordinator的主要功能就是将信息传递给所有订阅了Submission事件
//的客户端(包括分布信息的客户端本身)
public void Submit(string addressor, string address)
{
Console.WriteLine("{0} sent: {1}.", addressor,address);
//将发言者的化名和发言内容用事件参数类SubmitEventArgs类封装
//把SubmitEventArgs类的实例作为事件Submission的参数
SubmitEventArgs e = new SubmitEventArgs(addressor,address);
if (Submission != null)
{
Console.WriteLine("Broadcasting...");
// 触发事件,所有订阅了Submission事件的客户端接收到此事件后,执行相应的
//事件处理程序
Submission(this, e);
}
}
}
//定义一个抽象类RemotelyDelegatableObject,在其中定义函数SubmissionCallback
// 函数SubmissionCallback便是在客户端所指定的事件处理程序
//客户端必须从RemotelyDelegatableObject类中派生出自己定义的子类,并且要
//重载InternalSubmissionCallback函数,从而完成客户端需要完成的工作
public abstract class RemotelyDelegatableObject : MarshalByRefObject
{
public void SubmissionCallback (object sender, SubmitEventArgs submitArgs)
{
InternalSubmissionCallback (sender, submitArgs) ;
}
protected abstract void InternalSubmissionCallback (object sender,
SubmitEventArgs submitArgs) ;
}
服务器代码:
using System;
using System.Runtime.Remoting;
namespace ChatServer
{
/// <summary>
/// ChatServer的摘要说明。
/// </summary>
public class ChatServer
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
RemotingConfiguration.Configure("../../ChatServer.exe.config",false);
Console.WriteLine("The application server is running...");
Console.ReadLine();
}
}
}
服务器配置文件:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown mode="Singleton" type="ChatCoordinator,ChatCoordinator"
objectUri="Chat.rem"/>
</service>
<channels>
<channel ref="http" port="1234">
<serverProviders>
<provider ref="wsdl" />
<formatter ref="binary" typeFilterLevel="Full"/>
</serverProviders>
<clientProviders>
<formatter ref="binary"/>
</clientProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
客户端:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
namespace ChatClient
{
/// <summary>
/// ChatClientForm 的摘要说明。
/// </summary>
public class ChatClientForm : System.Windows.Forms.Form
{
private System.Windows.Forms.ListBox listBox;
private System.Windows.Forms.Button butSent;
private System.Windows.Forms.TextBox txtAddress;
private System.ComponentModel.Container components = null;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox txtAddressor;
private System.Windows.Forms.Label label3;
/// <summary>
/// 必需的设计器变量。
/// </summary>
ChatCoordinator chat_coordinator;
MyCallbackClass callback;
string _addressor;
private System.Windows.Forms.Label lbtime;
string _address;
//注意:将ChatClientForm()方法声明为protected,这样在MyCallbackClass类中不能
//直接调用它,而是通过下面的Instance()方法,来实现实例化,以保证仅有一个ChatClientForm
//对象
protected ChatClientForm()
{
CheckForIllegalCrossThreadCalls = false;
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
try
{
//读取客户端的配置文件
RemotingConfiguration.Configure("../../ChatClient.exe.config",false);
chat_coordinator = new ChatCoordinator();
lbtime.Text=chat_coordinator.CurrentTime();
callback = new MyCallbackClass () ;
//订阅Submission事件,并且指定它的事件处理程序。为事件处理程序创建一个
//新的委托,当事件发生时,便会触发事件处理程序
chat_coordinator.Submission += new
SubmissionEventHandler(callback.SubmissionCallback);
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.listBox = new System.Windows.Forms.ListBox();
this.txtAddress = new System.Windows.Forms.TextBox();
this.txtAddressor = new System.Windows.Forms.TextBox();
this.butSent = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.lbtime = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// listBox
//
this.listBox.BackColor = System.Drawing.SystemColors.Control;
this.listBox.ItemHeight = 12;
this.listBox.Location = new System.Drawing.Point(0, 56);
this.listBox.Name = "listBox";
this.listBox.Size = new System.Drawing.Size(376, 160);
this.listBox.TabIndex = 2;
//
// txtAddress
//
this.txtAddress.Location = new System.Drawing.Point(112, 288);
this.txtAddress.Multiline = true;
this.txtAddress.Name = "txtAddress";
this.txtAddress.Size = new System.Drawing.Size(136, 21);
this.txtAddress.TabIndex = 1;
this.txtAddress.Text = "";
this.txtAddress.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txtAddress_KeyDown);
//
// txtAddressor
//
this.txtAddressor.Location = new System.Drawing.Point(112, 240);
this.txtAddressor.Name = "txtAddressor";
this.txtAddressor.ReadOnly = true;
this.txtAddressor.Size = new System.Drawing.Size(128, 21);
this.txtAddressor.TabIndex = 3;
this.txtAddressor.Text = "";
//
// butSent
//
this.butSent.Location = new System.Drawing.Point(272, 288);
this.butSent.Name = "butSent";
this.butSent.Size = new System.Drawing.Size(64, 23);
this.butSent.TabIndex = 2;
this.butSent.Text = "发送";
this.butSent.Click += new System.EventHandler(this.butSent_Click);
//
// label1
//
this.label1.Location = new System.Drawing.Point(8, 240);
this.label1.Name = "label1";
this.label1.TabIndex = 5;
this.label1.Text = "您的呢称:";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label2
//
this.label2.Location = new System.Drawing.Point(0, 288);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(104, 23);
this.label2.TabIndex = 6;
this.label2.Text = "请输入所发信息:";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label3
//
this.label3.Font = new System.Drawing.Font("SimSun", 14.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(134)));
this.label3.Location = new System.Drawing.Point(96, 8);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(168, 40);
this.label3.TabIndex = 7;
this.label3.Text = "分布式会话";
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// lbtime
//
this.lbtime.Location = new System.Drawing.Point(272, 248);
this.lbtime.Name = "lbtime";
this.lbtime.TabIndex = 8;
//
// ChatClientForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(384, 333);
this.Controls.Add(this.lbtime);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.butSent);
this.Controls.Add(this.txtAddressor);
this.Controls.Add(this.txtAddress);
this.Controls.Add(this.listBox);
this.Name = "ChatClientForm";
this.Text = "ChatClient";
this.Closing += new System.ComponentModel.CancelEventHandler(this.ChatClientForm_Closing);
this.Load += new System.EventHandler(this.ChatClientForm_Load);
this.ResumeLayout(false);
}
#endregion
//声明一个静态属性_instance
private static ChatClientForm _instance;
//声明一个静态成员函数Instance,它保证在外部类中实例化一个ChatClientForm类时,
//仅有一个ChatClientForm实例被返回
public static ChatClientForm Instance()
{
if(_instance==null)
_instance=new ChatClientForm();
return _instance;
}
//AddItem方法实现向ListBox中添加条目
public void AddItem(string str)
{
listBox.Items.Add(str);
}
//公共属性Addressor返回发言人的用户名
public string Addressor
{
get
{
return _addressor;
}
}
private void ChatClientForm_Load(object sender, System.EventArgs e)
{
//创建Login对话框
Login LoginDlg=new Login();
DialogResult dlgResult;
//显示对话框
dlgResult=LoginDlg.ShowDialog();
if(LoginDlg.UserName==null)
{
this.Close();
return;
}
else
{
//如果输入不为空并且点击“确认”按钮后,将用户名传入ChatClient对话框
if(dlgResult==DialogResult.OK)
{
txtAddressor.Text=LoginDlg.UserName;
}
LoginDlg.Close();
}
}
private void butSent_Click(object sender, System.EventArgs e)
{
_addressor=txtAddressor.Text.ToString();
_address=txtAddress.Text.ToString();
chat_coordinator.Submit(_addressor,_address);
txtAddress.Clear();
txtAddress.Focus();
}
private void txtAddress_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
if(e.KeyCode==Keys.Enter)
{
_addressor=txtAddressor.Text.ToString();
_address=txtAddress.Text.ToString();
chat_coordinator.Submit(_addressor,_address);
txtAddress.Clear();
txtAddress.Focus();
}
}
private void ChatClientForm_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
chat_coordinator.Submission -= new
SubmissionEventHandler(callback.SubmissionCallback);
}
/// <summary>
///应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
//调用Instance()方法来实例化ChatClientForm类
Application.Run(Instance());
}
}
class MyCallbackClass : RemotelyDelegatableObject
{
private string _alias = null;
public MyCallbackClass () {}
//InternalSubmissionCallback方法被RemotelyDelegatableObject.SubmissionCallback()
//调用。SubmissionCallback()方法将通过代理SubmissionEventHandler被送回服务器
protected override void InternalSubmissionCallback (object sender, SubmitEventArgs submitArgs)
{
//生成一个ChatClientForm对象
ChatClientForm form=ChatClientForm.Instance();
_alias=form.Addressor;
// 如果检查信息发布者是自己,那么提示所发信息,并被告知信息
// 已经被发布
if (String.Compare(submitArgs.Addressor, _alias, true) == 0)
{
form.AddItem("Your message:");
form.AddItem(new String('-',60));
form.AddItem(submitArgs.Address);
form.AddItem(new String('-',60));
form.AddItem("Your message has been broadcast.");
}
//如果信息发布者是别人,那么输出发布者的呢称及所发布的内容
else
{
form.AddItem(submitArgs.Addressor
+"Broadcasts:");
form.AddItem(new String('_',60));
form.AddItem(submitArgs.Address);
form.AddItem(new String('_',60));
}
}
public override object InitializeLifetimeService()
{
return null;
}
}
}
login.cs
:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace ChatClient
{
/// <summary>
/// Login 的摘要说明。
/// </summary>
public class Login : System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btnEnter;
private System.Windows.Forms.TextBox txtName;
private System.Windows.Forms.Button button1;
/// <summary>
///必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
private string _name=null;
public Login()
{
//
// Windows 窗体设计器支持所必需的
//
InitializeComponent();
//
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
//
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.btnEnter = new System.Windows.Forms.Button();
this.txtName = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// label1
//
this.label1.Location = new System.Drawing.Point(16, 40);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(64, 23);
this.label1.TabIndex = 0;
this.label1.Text = "用户名:";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// btnEnter
//
this.btnEnter.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnEnter.Location = new System.Drawing.Point(40, 112);
this.btnEnter.Name = "btnEnter";
this.btnEnter.Size = new System.Drawing.Size(72, 24);
this.btnEnter.TabIndex = 2;
this.btnEnter.Text = "确认";
this.btnEnter.Click += new System.EventHandler(this.btnEnter_Click);
//
// txtName
//
this.txtName.Location = new System.Drawing.Point(88, 40);
this.txtName.Name = "txtName";
this.txtName.Size = new System.Drawing.Size(120, 21);
this.txtName.TabIndex = 1;
this.txtName.Text = "";
//
// button1
//
this.button1.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.button1.Location = new System.Drawing.Point(168, 112);
this.button1.Name = "button1";
this.button1.TabIndex = 3;
this.button1.Text = "取消";
//
// Login
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(320, 189);
this.Controls.Add(this.button1);
this.Controls.Add(this.txtName);
this.Controls.Add(this.btnEnter);
this.Controls.Add(this.label1);
this.Name = "Login";
this.Text = "Login";
this.ResumeLayout(false);
}
#endregion
public string UserName
{
get
{
return _name;
}
}
private void btnEnter_Click(object sender, System.EventArgs e)
{
txtName.Text=txtName.Text.Trim();
if(txtName.Text.Length==0)
{
MessageBox.Show("请输入您的呢称!","提示信息",
MessageBoxButtons.OK,MessageBoxIcon.Exclamation);
txtName.Focus();
return;
}
_name=txtName.Text.ToString ();
}
}
}
客户端配置文件:
<configuration>
<system.runtime.remoting>
<application>
<client>
<wellknown type="ChatCoordinator,ChatCoordinator"
url="http://localhost:1234/Chat.rem"/>
</client>
<channels>
<channel ref="http" port="0">
<clientProviders>
<formatter ref="binary" />
</clientProviders>
<serverProviders>
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
</application>
</system.runtime.remoting>
</configuration>
一运行就会出现刚才我说的问题。请哪位高手解决一下。谢谢啦,一定加分