Live

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
      最近对Google很感兴趣,特别是Gmail中实现的chat功能。web IM实际上一点也不陌生,不过大多数都比较慢,可能还是归根于传统的pull data的模式,为了达到实时,只有提高pull的频率,不过这始终不是办法。并且很浪费资源,因为即使没有你要的数据,你也会一直在请求。回头看 Gmail中的Chat程序,发现很快,基本上和使用GTalk客户端差不多,经过抓包分析,发现并不是定时去请求拿数据。
     还记得前两年流行聊天室的时候出现一种叫server push的东西,主要是实现从服务器端推数据到浏览器,以此来达到无刷新的聊天室。这两年开始流行Ajax,基于Ajax实现的聊天室也多了起来,不过实际上还是定时去请求服务器。
     对于这类IM软件来说如果能实现服务器直接push 数据到浏览器上,应该是一个很好的方案。网上google了一下,发现国外已经有人提出一个叫Comet的概念。来看看Comet和Ajax的不同之处:

当然,Comet不能取代Ajax,但是Comet的应用范围应该也非常广,比如上面说的IM软件,聊天室,证券系统等等实时性比较高的应用。目前比较成功的应用有gamil还有meebo(www.meebo.com)。
      这种服务器推数据的方式,应该要保持一个长时间的浏览器到服务器的连接,目前还不清楚gmail的实现方式,自己模拟了一个。实现浏览器访问一个web服 务器,一直处于联机状态,如果有数据就把上把数据推倒浏览器上,这里我们用WebServices来发数据。
原理是用IIS作服务器,客户请求之后在Page_Load不要返回,让浏览器一直处于下载状态。我们的Default.aspx 代码如下:
protected void Page_Load(object sender, EventArgs e)
    {
        if(Application["holy"]==null)
            Application.Add("holy",new Message());

        while (true)
        {
            lock (Application["holy"])
            {
                while (Monitor.Wait(Application["holy"]))
                {
                    Message message=(Message)Application["holy"];
                    if (message.Text != string.Empty)
                    {
                        this.Response.Write(message.Text+"\n");
                        this.Response.Flush();
                    }
                }       
            }
        }
    }
里面是一个无穷循环,进去之后线程被挂起,锁对象放在Application中。
然后新建一个WebService.asmx文件,用于发数据,主要是获取锁对象,然后解锁。WebMethod 如下:
[WebMethod]
    public int SendMessage(string message)
    {
        if (Application["holy"] == null)
            return 0;

        lock (Application["holy"])
        {
            ((Message)Application["holy"]).Text = message;
            Monitor.PulseAll(Application["holy"]);
        }
        return 1;
    }
最后Message类是用来传递消息的,同时也是锁:
public class Message
{
    private string text;

    public string Text
    {
        get { return text; }
        set { text = value; }
    }

    public Message()
    {
    }
}
编译,首先用FF访问Default.aspx页面,然后在打开webservice页面(就是WebService.asmx )如图:

现在浏览器一和我们的web服务连接好了,但是没有数据。我们利用web services发送一条数据“hello”,当我们单击启动按钮之后,FF马上就收到了数据:




再发一条:


上面访问Default.aspx 页面要用Firefox,不能用IE,不然页面上不会显示信息。通过测试发现实际上已经拿到数据,但是就是不现实,一定要关掉连接才会显示,不知道为什么。
上面的代码没有什么实用,只是希望大家也来讨论一下Comet这种新的开发模式。
附Gmail-chat抓包图:

再来看看我们试验产生的数据包:

对上面gmail-chat的数据包,发现一模一样。
posted on 2006-08-08 14:37  一唯  阅读(6585)  评论(50编辑  收藏  举报