流水不争先,争的是滔滔不绝

开源Comet服务器iComet:支持百万并发的Web端即时通讯方案

即时通讯软件开发 云聊IM 1793℃

前言

Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询、Comet技术、WebSocket技术、SSE(Server-sent Events)。

以上4种即时通讯技术各有各的优势和限制,很难决定最佳实践,开发者选型时根据自已的应用场景、开发代价、技术水平等选择适合自已的才是明智选择。

Comet技术简介

以即时通信为代表的web应用程序对数据的Low Latency要求,传统的基于轮询的方式已经无法满足,而且也会带来不好的用户体验。于是一种基于http长连接的“服务器推”技术便被hack出来。这种技术被命名为Comet,这个术语由Dojo Toolkit 的项目主管Alex Russell在博文Comet: Low Latency Data for the Browser首次提出,并沿用下来。

其实,服务器推很早就存在了,在经典的client/server模型中有广泛使用,只是浏览器太懒了,并没有对这种技术提供很好的支持。但是Ajax的出现使这种技术在浏览器上实现成为可能, google的gmail和gtalk的整合首先使用了这种技术。随着一些关键问题的解决(比如 IE 的加载显示问题),很快这种技术得到了认可,目前已经有很多成熟的开源Comet框架。

以下是典型的Ajax和Comet数据传输方式的对比,区别简单明了。典型的Ajax通信方式也是http协议的经典使用方式,要想取得数据,必须首先发送请求。在Low Latency要求比较高的web应用中,只能增加服务器请求的频率。Comet则不同,客户端与服务器端保持一个长连接,只有客户端需要的数据更新时,服务器才主动将数据推送给客户端。

关于iComet服务器

iComet 是一个使用 C++ 语言开发的支持百万并发连接的 comet/push 服务器, 支持百万级并发连接, 内存占用少, 性能优越. 可用于移动 App 的 Push Server(消息推送服务器), 或者用于 Web Push(Web 服务器推). 用于 Web Push 时, 支持的浏览器和操作系统平台包括: Safari(iOS, Mac), Firefox/Chrome(Windows, Mac), IE6+。

为何选择iComet

对于开发者, 为了快速和方便的开发, 应该选择一个支持 Comet 技术的 Web 服务器和一套 JavaScript 库(当然iComet也有开源的Java和Android客户端库可用)。iComet 就是这样的一套解决方案。

相关资源

  1. iComet服务器工程主页:https://github.com/ideawu/icomet
  2. iComet的Java/Android客户端库:https://github.com/DuoZhang/iCometClient4j
  3. iComet的客户端Demo:https://github.com/ideawu/icomet-demos
  4. iComet的Web端Demo在线体验:http://www.ideawu.com/icomet/chat/

客户端Demo截图

Web端:

Andriod端:

iComet 技术概览

iComet的技术应用场景

iComet 的处理流程

iComet 分布式部署思路

iComet 本身没有分布式方面的工具。我可以说一个思路:

  1. 部署多台 icomet-server 实例;
  2. 用户调用 sign 申请通道时, 根据 uid 哈希到其中一台;
  3. 当往用户推送消息时, 根据uid哈希推送到他所在的那一台icomet-server上。

如果你可以开发, 那便写程序订阅 psub 接口, 在一个中心节点保存uid和icomet-server的对应关系(路由表)。

如何支持百万并发连接 C1000K

需要两个步骤:

  1. 第一步: 操作系统要支持, 参考 http://www.ideawu.net/blog/archives/740.html;
  2. 第二步: 修改 icomet.conf,设置 max_channels: 1000000。

iConet服务器内存占用情况

内存占用为 2.7KB / 每连接。

iComet 简明开发者指南

iComet服务端编译和运行

编译:

wget --no-check-certificate [url=https://github.com/ideawu/icomet/archive/master.zip]https://github.com/ideawu/icomet/archive/master.zip[/url]
unzip master.zip
cd icomet-master/
make

Start icomet server:

./icomet-server icomet.conf
# or run as daemon
./icomet-server -d icomet.conf
# stop
./icomet-server icomet.conf -s stop

Make a test via curl:

curl -v "http://127.0.0.1:8100/sub?cname=12&seq=1"
# open another terminal
curl -v "http://127.0.0.1:8000/push?cname=12&content=hi"

Web端JavaScript调用方法

var comet = new iComet({
    channel: 'abc',
    signUrl: 'http://127.0.0.1:8000/sign',
    subUrl: 'http://127.0.0.1:8100/sub',
    callback: function(content){
        // on server push
        alert(content);
    }
});

Java/Android客户端库

iComet的Java/Android客户端库:https://github.com/DuoZhang/iCometClient4j

iComet的客户端Demo:https://github.com/ideawu/icomet-demos

Nginx + icomet

You can integrate icomet with nginx. If you are running you website on port 80 with domain www.test.com. That is you visit your website home page with this url:

http://www.test.com/

Then you want to run icomet on the same server with port 80, for the concern of firewall issue. You can config nginx to pass request to icomet:

location ~ ^/icomet/.* {
    rewrite ^/icomet/(.*) /$1 break;
 
    proxy_read_timeout 60;
    proxy_connect_timeout 60;
    proxy_buffering off;
    proxy_pass   [url=http://127.0.0.1:8100;]http://127.0.0.1:8100;[/url]
}

Then, this url is used to subscribe to icomet channel xxx:

http://www.test.com/icomet/sub?cname=xxx
版权声明:部分文章、图片等内容为用户发布或互联网整理而来,仅供学习参考。如有侵犯您的版权,请联系我们,将立刻删除。
点击这里给我发消息