码迷,mamicode.com
首页 > 其他好文 > 详细

socket.io与sticky-session, 多个socket.io实例带来的问题

时间:2015-10-01 23:04:57      阅读:647      评论:0      收藏:0      [点我收藏+]

标签:

websocket的出现使得从服务器向浏览器推送数据更加容易。但是低版本的浏览器不支持websocket,这时socket.io出现了。

使用socket.io的应用在支持websocket的浏览器运行的时候使用websocket,而在低版本的浏览器中则使用传统的方式与服务器交互(例如long-polling及其他的方式)。

long-polling的应用实现方式是这样的,客户端向服务器端发起请求,服务器端不会马上返回,而是保持这个连接直到服务器需要推送信息给客户端时,才返回给客户端数据。客户端接收到数据以后会再次发送一个请求,如此循环。

socket.io支持使用long-polling的客户端,这个特点使得我们的网站在低版本的浏览器也能运行,但是这会给socket.io服务器端程序带来一个问题。

比如我们需要用socket.io编写一个聊天程序,每当有一个新的用户时,建立一个新连接,服务器在内存中保存当前的所有连接。当需要给所有用户广播信息的时候,我们遍历所有的连接,给每个连接写数据。类似于:

//示意代码
var clients = []; //所有的用户

server.on(‘broadcast‘, function(){  
   for client in clients { 
       writeData(client, ‘hi‘);
   }
});

现在我们来考虑一下writeData这个方法要怎么实现,因为要支持使用long-polling的客户端,long-polling是由多次请求组成的,所以在两次请求之间客户端和服务器端没有连接,假如这时需要推送数据到客户端,我们需要在服务器端把要推送的数据临时存下来,等待客户端发起请求的时候,再把数据发送到客户端。服务器端代码类似:

var long_polling_clients = [];  
function writeData(client, data){  
    long_polling_clients.push([client, data]);
}

server.on(‘request‘, function(){  
  //从long_polling_clients取得client
  //发送数据到客户端
});

当服务器端只有一台服务器的时候,程序没有问题,客户端发送的每次请求都连接到同一台服务器。

但是当服务器端有多台服务器时,程序就有可能出错。

假如C1客户端先连接到A服务器,并且服务器需要推送消息到客户端,这个服务器的会把要发送的消息和对应的客户端保存起来,等待客户端请求。

//A服务器
var long_polling_clients = [[客户端1, 消息]];  

下一次客户端请求连接到了B服务器,B服务器并没有向C1客户端推送消息,因此B服务器的内存中没有记录C1客户端,所以不会向C1客户端写数据,这样程序就出错了。

//B服务器
var long_polling_clients = []  

为了解决这个问题,最简单的办法是每次客户端连接服务器的时候都连同一台服务器,这可以使用nginx这样的工具来实现。

但是有时为了利用多核,我们会在服务器上运行多个socket.io实例,每个实例都有自己的内存空间。这时候怎么办呢?我们需要用到sticky-session这个库。

这个库调用cluster创建了多个socket.io实例,并且总是把相同ip的请求发送到同一个socket.io实例。

当然我们可以选择不把[客户端,消息]保存在内存中,而是用其他存储方式保存例如redis,这样多台服务器,多个socket.io实例都可以共享数据。

 

原文链接: http://suyuan.me/socket-ioyu-sticky-session/

socket.io与sticky-session, 多个socket.io实例带来的问题

标签:

原文地址:http://www.cnblogs.com/suyuan1203/p/4851698.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!