网上即时聊天原理(mochiweb+jquery实现)
2 操作:
分别打开两个网页,然后,对textfield中输入内容,在另一个网页中会即时显现.
3 Comet
Comet 是一项很时髦的技术。其目的很简单:由于历史原因,目前 HTTP 协议信息都是客 户端向服务器要(Poll),服务器没有办法推送信息给客户端(Sever Push)。这在实现 某些应用的时候就会遇到麻烦。例如:
- 当邮件服务器收到新的邮件时,及时报告给用户,如果他在线的话(GMail 这样做了)
- 当 Web Chat 服务器收到新的信息时,及时发送信息到相应的在线用户(Web Chat 的基本需求)。
- 聊天时提示你对方正在输入(时下 IM 客户端很时髦的一个功能)。
Comet 技术对服务端的要求还是很高的,Long Polling减少了网络流量,但是服务端的连 接数并没有减少。因此基于 Comet 的应用,很容易在 Scale(伸缩性)上出现问题。使用 Erlang + MochiWeb,还是很好的利用了 Erlang 可以轻松建立大量连接这个特性。需要指 出的是,很可能 Comet 应用的时髦,将会很大程度上促进了业界对 Erlang 的关注。
4 代码讲解
index.html
function get(){ $.ajax({ type: "GET", url: "chat", cache:false, success:getMsg }); } function getMsg(data){ $("#history").append(new Date().toLocaleString()+":"+data+"<br/>"); get(); }
在index.html 加载完比后,会先调用一次:
get();
上面的函数是以GET方式向服务器端发起请求的代码,可以看出,在回调方法中,再次调 用get() 方法,向服务器端发起请求。这跟那种每隔一定时间向服务器端请求一次看有 没有新的消息的方式完全不一样。 因为这种以GET方式发起的请求,在服务器端是阻塞的,即由服务器端来控制 ,如果没 有新的消息就不返回(达到超时时间除外(代码中设为20s))。
$('#send').click( function(){ $.ajax({ type: "POST", url: "chat", cache:false, data: "message="+$("#message").val(), success: function(msg){ $("#status").empty(); // remove children $("#status").append(new Date().toLocaleString()+":"+msg); // add child } }); } ); });
点击发送按钮的时候,会以POST方式,向服务器发送一条消息, 服务器在接到这条消息后,会进行如下处理:
Data = Req:parse_post(), Room = get_the_room(), % post io:format("message from post:~p~n",[proplists:get_value("message", Data)]) , Room ! {self(), post, list_to_binary(proplists:get_value("message", Data))},
某进程接到上面发送的消息会,会查看room 中有哪些用户在等待, 然后一一取出,将上面接收到的那条信息分别发送给他们 ,然后清空等待队列 那些以GET方式请求的客户端到此时才返回(如果没有超时的话。)
{From, post, Message} -> From ! posted, lists:foreach(fun(User) -> % broadcast the message User ! Message end, Users), %% room(Users), %% 所有等待的用户都会接收的消息, %% 从队列中去掉他们 room([]), io:format("~n",[]) ; %% room([]);