谈到socket.io,就不能不提一下websocket,websocket是html5的新特性之一,多少web开发者为之兴奋,websocket可以使web程序客户端和服务端之间保持长连接,可以实现实时通讯,而且API简单易用,但是由于浏览器的支持不同,又是一个头疼的事情。后来,socket.io出现了,在某种程度上,socket.io就是websocket,其实socket.io与websocket不是一回事,而且websocket可以说是socket.io的一个子集,socket.io的底层实现其实有5种方式,websocket只是其中一种,只不过在默认的情况下,我们建立的socket.io连接,底层也是调用websocket的实例。当我们io.connect()建立一个socket连接的时候,返回的是namespace实例,namespace实例中有个socket实例,当新建一个连接,或者发送一条消息的时候,namespace->socket->transport->websocket(xhrpolling...),其实发送一条消息真正的发送者还是底层的websocket或是xhrpolling或其他的几种,而socket.io只是一个组织者,当我们需要建立连接的时候,它自己会在其内部挑选一种连接方式,然后实现连接。具体的socket.io内部实现还需要进一步学习源码。
本文的水平还只是在socket.io的实践上,其内核具体实现还需要不断探索。接下来就分享一些最近在socket.io开发中的一些经验,主要是客户端的,服务端的了解也不深,但是相信也是大同小异。
首先就是简单介绍socket.io的用法:
- socket = io.connect("http://" + config.serverip + ":" + config.serverport, { 'reconnect': true });
- socket.on('connect', function(data) {
- console.log("Connected to Server");
- global.reconnectFailCount = 0;
- });
- socket.on('connect_failed', function(data) {
- console.log("connect_failed to Server");
- });
- socket.on('error', function(data) {
- console.log("error");
- alert("连接服务器失败!!!");
- });
- socket.on('reconnecting', function (data) {
- console.log("reconnecting");
- global.reconnectFailCount++;
- if (global.reconnectFailCount >= 6) {
- alert("连接服务器失败,请检查您当前的网络");
- }
- });
- socket.on('reconnect', function (data) {
- console.log("reconnect");
- global.reconnectFailCount--;
- });
- socket.on('disconnect', function (data) {
- console.log("disconnect");
- });
如上所示,我们就创建了一个socket连接,这里需要强调一点,默认情况下,无论我们创建了多少次socket连接,指向都是同一个socket实例,除非我们在connect()的第二个参数中指定"force new socket"强制建立一个新的连接。socket实例监听了其connect,connect_failed等等事件,不要小看这些事件,其实都很有用,弄明白他们,socket.io基本无大问题,我们一一来分析一下。刚刚创建一个socket的时候,其实这只是一个空的socket,而且并未分配一个id,只有当与服务器连接成功后,才会生成一个id,因此我们在connect中才能得到获取socket的id,有些时候,socket的id是很有用的,有时会用于存储对应socket的用户信息。socket连接成功后,服务端与客户端会定时发送心跳包,若某一方长时间未回应,默认连接断开,当我们的网络不稳定或者有其他影响连接的因素存在的时候,则会与服务器断开连接,断开时会触发disconnect监听,若我们没有声明reconnect的时候,断开就不再与服务器重新连接,若我们在创建的时候如上声明了reconnect:true,那么断开后客户端还是会尝试新的连接,就会触发reconnecting监听,若连接未成功,会继续尝试多次连接,若连接成功,则会触发reconnect监听,此时,原有的socket连接已经不再,内部会创建一个新的连接,并且socket得到一个新的id,最后会再一次触发connect监听。
虽然这里暂时并没有深入socket.io内核实现,但是明白了这些,利用socket.io实现即时通讯就完全没有问题,而且连接比较稳定,即使中间会有重连小插曲,处理得好,完全不会有问题。以后再慢慢深入讨论。