其实对于一个WebIM来说,我们一般都几种方式来实现
1.服务器拉送方式:就是客户端主动定时的去服务器端获取信息,一般我们可以通过 Ajax控件+定时器 来实现,优点:实现简单,缺点:服务器承受的压力重
2.服务器推送方式:就是服务器主动将获取到的信息,发送给客户端,Asp.net我们可以通过 IHttpAsyncHandler这个接口来实现,优点:服务器承受的压力小 缺点:服务器 和客户端同时配合编写(js)
3.Flash Socket方式:通过在网页中嵌入Flash,编写Socket程序 通过AS 3.0语言,Socket编程,优点:并发量大,服务器压力小,缺点:浏览器中要支持Flash,加载Flash
下面我实现的是第二种:
它实现的原理很简单,浏览器向服务器发送一个异步请求,服务器接到请求之后,去内存中查找信息,如果有,就直接处理该请求,如果没有,我们可以把该请求暂存到服务器一段时间,如果在该时间段内,有符合自己信息的到来,我们就直接处理,否则我们要丢掉该请求(其实请求丢掉之后,如果客户端任然在线,客户端会重新在次发送请求,就像是心跳包)
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Web;
namespace DNCCFrameWork.Chat
{
/// <summary>
/// Chat聊天异步处理程序
/// </summary>
public class ChatAsyncHandler : IHttpAsyncHandler
{
//接受客户端请求
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
{
System.IO.Stream stream = context.Request.InputStream;
byte[] b = ReadDate(stream);
string str = context.Server.UrlDecode(context.Request.ContentEncoding.GetString(b));
Hashtable ht = SplitRequestPara(str);
string type = ht["type"] as string;
string message = ht["content"] as string;
string sendUser = ht["sendusers"] as string;
string receiveUser = ht["receiveusers"] as string;
IChatMessage chatMessage = new ChatMessage();
chatMessage.Type = type;
chatMessage.Content = message;
chatMessage.SendUser = sendUser;
chatMessage.ReceiveUser = receiveUser;
ChatAsyncResult chatAsyncResult = new ChatAsyncResult(context, cb, extraData, chatMessage);
IChat chat = new ChatDefault();
chat.IM(chatAsyncResult);
return chatAsyncResult;
}
#region 读流中的全部数据
private byte[] ReadDate(System.IO.Stream stream)
{
byte[] buff = new byte[stream.Length];
int curOffset = 0;
int totalCount = 0;
int readCount = 0;
int size = buff.Length;
while (totalCount < size)
{
int exceptSize = size - totalCount;
readCount = stream.Read(buff, curOffset, exceptSize);
curOffset += readCount;
totalCount += readCount;
}
return buff;
}
#endregion
#region 分离请求数据
private Hashtable SplitRequestPara(string str)
{
Hashtable ht = new Hashtable();
string[] str1 = str.Split(new char[] { '&' });
foreach (string temp in str1)
{
string[] str2 = temp.Split(new char[] { '=' });
if (str2.Length == 2)
{
if (!ht.ContainsKey(str2[0].ToLower().ToString()))
{
ht.Add(str2[0].ToLower().ToString(), str2[1].ToString());
}
}
}
return ht;
}
#endregion
public void EndProcessRequest(IAsyncResult result)
{
}
#region IHttpHandler接口
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
}
#endregion
#region 请求检测
private bool RequestCheck(IChatMessage cm)
{
bool status = true;
if (string.IsNullOrEmpty(cm.Type))
{
status = false;
}
else
{
try
{
cm.Type = Common.Security.CryptoTextBase.ProcessText(cm.Type, false);
}
catch
{
status = false;
}
}
if (string.IsNullOrEmpty(cm.SendUser))
{
status = false;
}
if (string.IsNullOrEmpty(cm.ReceiveUser))
{
status = false;
}
return status;
}
#endregion
}
}
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Web;
namespace DNCCFrameWork.Chat
{
/// <summary>
/// Chat聊天异步处理程序
/// </summary>
public class ChatAsyncHandler : IHttpAsyncHandler
{
//接受客户端请求
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)
{
System.IO.Stream stream = context.Request.InputStream;
byte[] b = ReadDate(stream);
string str = context.Server.UrlDecode(context.Request.ContentEncoding.GetString(b));
Hashtable ht = SplitRequestPara(str);
string type = ht["type"] as string;
string message = ht["content"] as string;
string sendUser = ht["sendusers"] as string;
string receiveUser = ht["receiveusers"] as string;
IChatMessage chatMessage = new ChatMessage();
chatMessage.Type = type;
chatMessage.Content = message;
chatMessage.SendUser = sendUser;
chatMessage.ReceiveUser = receiveUser;
ChatAsyncResult chatAsyncResult = new ChatAsyncResult(context, cb, extraData, chatMessage);
IChat chat = new ChatDefault();
chat.IM(chatAsyncResult);
return chatAsyncResult;
}
#region 读流中的全部数据
private byte[] ReadDate(System.IO.Stream stream)
{
byte[] buff = new byte[stream.Length];
int curOffset = 0;
int totalCount = 0;
int readCount = 0;
int size = buff.Length;
while (totalCount < size)
{
int exceptSize = size - totalCount;
readCount = stream.Read(buff, curOffset, exceptSize);
curOffset += readCount;
totalCount += readCount;
}
return buff;
}
#endregion
#region 分离请求数据
private Hashtable SplitRequestPara(string str)
{
Hashtable ht = new Hashtable();
string[] str1 = str.Split(new char[] { '&' });
foreach (string temp in str1)
{
string[] str2 = temp.Split(new char[] { '=' });
if (str2.Length == 2)
{
if (!ht.ContainsKey(str2[0].ToLower().ToString()))
{
ht.Add(str2[0].ToLower().ToString(), str2[1].ToString());
}
}
}
return ht;
}
#endregion
public void EndProcessRequest(IAsyncResult result)
{
}
#region IHttpHandler接口
public bool IsReusable
{
get { return false; }
}
public void ProcessRequest(HttpContext context)
{
}
#endregion
#region 请求检测
private bool RequestCheck(IChatMessage cm)
{
bool status = true;
if (string.IsNullOrEmpty(cm.Type))
{
status = false;
}
else
{
try
{
cm.Type = Common.Security.CryptoTextBase.ProcessText(cm.Type, false);
}
catch
{
status = false;
}
}
if (string.IsNullOrEmpty(cm.SendUser))
{
status = false;
}
if (string.IsNullOrEmpty(cm.ReceiveUser))
{
status = false;
}
return status;
}
#endregion
}
}