我们在传统的web程序当中比较头疼的一件事是屏幕的刷新感。虽然有server push的技术,但在ie中较难实现。现在webservice给了我们这样一个机会,大家都知道webservice是基于soap的,而soap是xml的应用,如果你曾经用过ms xml sdk3.0的话就会知道里面有个xmlhttp方法,其实在那时我们就已经可以用xmlhttp的方式替代form了,也是无刷新的,其实准确地说是局部刷新,下面我们来看一下怎样做,先做一个chat webservice, 首先来分析一下,一个聊天室应具备的两个要素人和消息,这样我们可以建立一个类型(记得我在以前说过类也是类型),它包含这样两个要素。
///chatmessage.cs
using system;
namespace chat
{
/// <summary>
/// chatmessage类封装了两个string变量:userlists–用户列表,messages–要传递的信息
/// </summary>
public class chatmessage
{
public string userlist, messages;
}
}
第二个我们要建立的是什么呢?一个聊天室应能存储在线成员的名字及访问时间
///member.cs
using system;
namespace chat
{
/// <summary>
/// member类为每个聊天者封装了server端的变量
/// </summary>
public class member
{
// 存储消息的队列
public string username, msgqueue;
// 判断滞留事件以便踢人
public system.datetime lastaccesstime;
// the constructor
public member(string nickname)
{
this.username=nickname;
this.lastaccesstime=datetime.now;
}
}
}
接下来我们就应该做这个asmx了
///chatwebservice.asmx
using system;
using system.collections;
using system.componentmodel;
using system.data;
using system.diagnostics;
using system.web;
using system.web.services;
namespace chat
{
/// <summary>
/// summary description for chatwebservice.
/// </summary>
[webservice (namespace = "http://localhost/chat/", description = "this service provides an chat service")]
public class chatwebservice : system.web.services.webservice
{
public chatwebservice()
{
//codegen: this call is required by the asp.net web services designer
initializecomponent();
}
#region component 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()
{
}
#endregion
/// <summary>
/// clean up any resources being used.
/// </summary>
protected override void dispose( bool disposing )
{
}
[webmethod(description="接收用户名作为参数存储到application对象中")]
public string login(string username)
{
// ascertain that all the registered chat participants are active
checkmemberslist();
// synchronization lock
application.lock();
// get the collection of keys for the application variables
string[] members = application.allkeys;
// are there any registered chat members? & the present request is for a unique nick name?
if ((members.length>0)&&(array.indexof(members,username)>-1))
{
throw new exception("该用户已存在!");
}
// create a new member object for this participant
member newmember = new member(username);
// add this new member to the collectionof application level variables
application.add(username, newmember);
// synchronization unlock
application.unlock();
// go and get the list of current chat participants and retrun the list
return getmemberslist();
}
[webmethod(description="getmsg方法用用户名和消息为参数返回一个chatmessage对象,包括要传递的消息和用户列表")]
public chatmessage xchangemsgs(string username, string msg)
{
// ascertain that all the registered chat participants are active
checkmemberslist();
// synchronization lock
application.lock();
// get the collection of keys for the application variables
string[] members = application.allkeys;
if ((members.length==0)||(array.indexof(members,username)==-1))
// are there any registered chat members? & the present request is for a unique nick name?
{
throw new exception("你当前可能没有登陆或登陆超时,请重新登陆!");
}
chatmessage retmsg = new chatmessage();
retmsg.userlist = getmemberslist();
// loop through all the chat participants serverside member objects and
// add the message just received in their waiting message queue
for (int x=0;x<members.length;x++)
{
member temp = (member)application[members[x]];
temp.msgqueue+=("<br><font color = red>" + username + " 说:<br></font><font color = blue>" + msg);
if (temp.username == username)
{
retmsg.messages = temp.msgqueue;
temp.msgqueue="";
temp.lastaccesstime=datetime.now;
}
}
// synchronization unlock
application.unlock();
return retmsg;
}
[webmethod(description="getmsg方法用username为参数返回一个chatmessage对象,包括要传递的消息和用户列表")]
public chatmessage getmsgs(string username)
{
application.lock();
checkmemberslist();
application.lock();
string[] members = application.allkeys;
if ((members.length==0)||(array.indexof(members,username)==-1))
{
throw new exception("unknown user. please login with a username");
}
chatmessage retmsg = new chatmessage();
retmsg.userlist = getmemberslist();
member temp = (member)application[username];
retmsg.messages = temp.msgqueue;
temp.msgqueue="";
temp.lastaccesstime=datetime.now;
application.unlock();
return retmsg;
}
public string getmemberslist()
{
application.lock();
string userlist = "";
string[] members = application.allkeys;
application.unlock();
for (int x=0;x<members.length;x++)
{
member temp = (member)application[members[x]];
userlist += (temp.username+"\n");
}
return userlist;
}
private void checkmemberslist()
{
string[] members = application.allkeys;
arraylist removelist = new arraylist();
for (int x=0;x<members.length;x++)
{
member temp = (member) application[members[x]];
int test = (datetime.now.subtract(temp.lastaccesstime)).minutes;
if (test > 2)
{
removelist.add(members[x]);
}
}
// users = null;
for (int count = 0;count<removelist.count;count++)
{
application.remove((string)removelist[count]);
}
return;
}
}
}
