namespace RoomStatusTest
{
public delegate void StatusEvent(object sender,int iStatus);
/// <summary>
/// WatchStatus 的摘要说明。
/// </summary>
public class WatchStatus:System.MarshalByRefObject
{
public event StatusEvent Status;
public Thread StatusThread;
private const string CONNSTR="Data Source=fanhui;Initial Catalog=dbname;User ID=sa;PWD=sa;Pooling=false";
private static int Proceadd=0;
private static int Procedel=0;
private static int Proceupdate=0;
private static int iRefresh=-1;
private static bool brefresh=true;
public int Refresh
{
get{return iRefresh;}
}
public WatchStatus()
{
//
// TODO: 在此处添加构造函数逻辑
//
Console.WriteLine("Begin WatchStatus"); }
/// <summary>
/// 启动线程函数,由客户端调用
/// </summary>
public void StartMyThread()
{
StatusThread=new Thread(new ThreadStart(this.Execute));
StatusThread.Name="Watch Room Status!";
StatusThread.Priority=ThreadPriority.Highest;
if(StatusThread.ThreadState==ThreadState.Unstarted)
StatusThread.Start();
}
/// <summary>
/// 线程执行函数
/// </summary>
private void Execute()
{
Status(this,1111111111);
do
{
Check();
Console.WriteLine("执行新的查询!"); Thread.Sleep(3000);
}while(true);
}
/// <summary>
/// 负责扫描数据库,并将结果事件通知客户端
/// </summary>
private void Check()
{
SqlConnection sc=new SqlConnection(CONNSTR);
sc.Open();
SqlCommand scmd=new SqlCommand("Proc_Refresh",sc);
scmd.CommandType=CommandType.StoredProcedure; scmd.Parameters.Add(new SqlParameter("@add",
SqlDbType.Int,
0,
""
));
scmd.Parameters.Add(new SqlParameter("@del",
SqlDbType.Int,
0,
""));
scmd.Parameters.Add(new SqlParameter("@update",
SqlDbType.Int,
0,
""
));
scmd.Parameters.Add(new SqlParameter("@Refresh",
SqlDbType.Int,
0,
""));
scmd.Parameters["@add"].Direction=ParameterDirection.InputOutput;
scmd.Parameters["@del"].Direction=ParameterDirection.InputOutput;
scmd.Parameters["@update"].Direction=ParameterDirection.InputOutput;
scmd.Parameters["@Refresh"].Direction=ParameterDirection.InputOutput;
scmd.Parameters["@add"].Value=WatchStatus.Proceadd;
scmd.Parameters["@del"].Value=WatchStatus.Procedel;
scmd.Parameters["@update"].Value=WatchStatus.Proceupdate;
if(WatchStatus.brefresh)
scmd.Parameters["@Refresh"].Value=-1;
else
scmd.Parameters["@Refresh"].Value=0;
WatchStatus.brefresh=false;
try
{
scmd.ExecuteNonQuery();
iRefresh=(int)scmd.Parameters["@Refresh"].Value;
Console.WriteLine("fdasfd");
switch(iRefresh)
{
case -1:
case 4:
WatchStatus.Proceadd=(int)scmd.Parameters["@add"].Value;
WatchStatus.Procedel=(int)scmd.Parameters["@del"].Value;
WatchStatus.Proceupdate=(int)scmd.Parameters["@update"].Value;
Status(this,11);
break;
case 1:
WatchStatus.Proceadd=(int)scmd.Parameters["@add"].Value;
Status(this,22);
break;
case 0:
WatchStatus.Procedel=(int)scmd.Parameters["@del"].Value;
Status(this,33);
break;
case 2:
WatchStatus.Proceupdate=(int)scmd.Parameters["@update"].Value;
Status(this,44);
break;
}
}
catch
{
}
sc.Close();
} }
}
{
public delegate void StatusEvent(object sender,int iStatus);
/// <summary>
/// WatchStatus 的摘要说明。
/// </summary>
public class WatchStatus:System.MarshalByRefObject
{
public event StatusEvent Status;
public Thread StatusThread;
private const string CONNSTR="Data Source=fanhui;Initial Catalog=dbname;User ID=sa;PWD=sa;Pooling=false";
private static int Proceadd=0;
private static int Procedel=0;
private static int Proceupdate=0;
private static int iRefresh=-1;
private static bool brefresh=true;
public int Refresh
{
get{return iRefresh;}
}
public WatchStatus()
{
//
// TODO: 在此处添加构造函数逻辑
//
Console.WriteLine("Begin WatchStatus"); }
/// <summary>
/// 启动线程函数,由客户端调用
/// </summary>
public void StartMyThread()
{
StatusThread=new Thread(new ThreadStart(this.Execute));
StatusThread.Name="Watch Room Status!";
StatusThread.Priority=ThreadPriority.Highest;
if(StatusThread.ThreadState==ThreadState.Unstarted)
StatusThread.Start();
}
/// <summary>
/// 线程执行函数
/// </summary>
private void Execute()
{
Status(this,1111111111);
do
{
Check();
Console.WriteLine("执行新的查询!"); Thread.Sleep(3000);
}while(true);
}
/// <summary>
/// 负责扫描数据库,并将结果事件通知客户端
/// </summary>
private void Check()
{
SqlConnection sc=new SqlConnection(CONNSTR);
sc.Open();
SqlCommand scmd=new SqlCommand("Proc_Refresh",sc);
scmd.CommandType=CommandType.StoredProcedure; scmd.Parameters.Add(new SqlParameter("@add",
SqlDbType.Int,
0,
""
));
scmd.Parameters.Add(new SqlParameter("@del",
SqlDbType.Int,
0,
""));
scmd.Parameters.Add(new SqlParameter("@update",
SqlDbType.Int,
0,
""
));
scmd.Parameters.Add(new SqlParameter("@Refresh",
SqlDbType.Int,
0,
""));
scmd.Parameters["@add"].Direction=ParameterDirection.InputOutput;
scmd.Parameters["@del"].Direction=ParameterDirection.InputOutput;
scmd.Parameters["@update"].Direction=ParameterDirection.InputOutput;
scmd.Parameters["@Refresh"].Direction=ParameterDirection.InputOutput;
scmd.Parameters["@add"].Value=WatchStatus.Proceadd;
scmd.Parameters["@del"].Value=WatchStatus.Procedel;
scmd.Parameters["@update"].Value=WatchStatus.Proceupdate;
if(WatchStatus.brefresh)
scmd.Parameters["@Refresh"].Value=-1;
else
scmd.Parameters["@Refresh"].Value=0;
WatchStatus.brefresh=false;
try
{
scmd.ExecuteNonQuery();
iRefresh=(int)scmd.Parameters["@Refresh"].Value;
Console.WriteLine("fdasfd");
switch(iRefresh)
{
case -1:
case 4:
WatchStatus.Proceadd=(int)scmd.Parameters["@add"].Value;
WatchStatus.Procedel=(int)scmd.Parameters["@del"].Value;
WatchStatus.Proceupdate=(int)scmd.Parameters["@update"].Value;
Status(this,11);
break;
case 1:
WatchStatus.Proceadd=(int)scmd.Parameters["@add"].Value;
Status(this,22);
break;
case 0:
WatchStatus.Procedel=(int)scmd.Parameters["@del"].Value;
Status(this,33);
break;
case 2:
WatchStatus.Proceupdate=(int)scmd.Parameters["@update"].Value;
Status(this,44);
break;
}
}
catch
{
}
sc.Close();
} }
}
客户端调用:
class Client
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
RemotingConfiguration.Configure("../../Client.exe.config"); EventSink sink = new EventSink();
WatchStatus obj=new WatchStatus();
// register client sink in server - subscribe to event
obj.Status += new StatusEvent(sink.StatusHandler);
obj.StartMyThread();
Console.WriteLine("Hit to exit");
Console.ReadLine();
}
}
-------------------------
同时启动两个客户端,第一个启动的客户端也输出了第二个客户端启动线程时的触发事件:
Status(this,1111111111);
说明在服务器上为每一个客户端都启动了线程啊?!怎么才能只启动一个线程?
在客户连接的时候,自动注册自己。这样服务端就有了所有客户端的句柄。服务端启动一个线程,查询数据之后,调用所有的客户端,发送消息过去。或者让客户端自动向服务端的DataChangeEvent注册一个delegate,服务端主动发起这个event就可以了
sample我倒是有一个,但是只是说怎么用delegate的,其实你只要自己产生一个不断查询的线程,一旦有数据变化,直接调用里面的event,把参数传给他就好了。
这样引出另一个问题,就是如果当没有客户端引用的时候要中断线程,这样就要在romoting对象上增加一个引用计数器来控制,我想知道服务器怎么知道一个客户端断开连接(不论正常断开还是死机)?
这样你要知道每个客户端的channel了?