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

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/

时间: 2024-10-22 09:50:25

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

Linux统系统开发12 Socket API编程3 TCP状态转换 多路IO高并发select poll epoll udp组播 线程池

[本文谢绝转载原文来自http://990487026.blog.51cto.com] Linux统系统开发12 Socket API编程3 TCP状态转换 多路IO高并发select  poll  epoll udp组播 线程池 TCP 11种状态理解: 1,客户端正常发起关闭请求 2,客户端与服务端同时发起关闭请求 3,FIN_WAIT1直接转变TIME_WAIT 4,客户端接收来自服务器的关闭连接请求 多路IO转接服务器: select模型 poll模型 epoll模型 udp组播模型 线

网络编程——基于TCP协议的Socket编程,基于UDP协议的Socket编程

Socket编程 目前较为流行的网络编程模型是客户机/服务器通信模式 客户进程向服务器进程发出要求某种服务的请求,服务器进程响应该请求.如图所示,通常,一个服务器进程会同时为多个客户端进程服务,图中服务器进程B1同时为客户进程A1.A2和B2提供服务. Socket概述 ①   所谓Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过“套接字”向网络发出请求或者应答网络请求. ②   Socket是连接运行在网络上的两个程序间的双向通信的端点. ③  

socket 由浅入深 系列函数(五)socket 阻塞 与 非阻塞

socket 阻塞 与 非阻塞 author:songyanwu 1 概念理解 其实在我们在进行网络编程,在理解阻塞与非阻塞同时,还应该清楚同步与异步! 同步与阻塞 同步和阻塞是不同的,可是有时候在理解有会很模糊: 同步:事情一件件的做,做完一件返回一件,做不完不回复也不返回. 阻塞;  阻塞调用是指调用结果返回之前,当前线程会被挂起(线程进入非可执行状态,在这个状态下,cpu不会给线程分配时间片,即线程暂停运行).函数只有在得到结果之后才会返回. 说明:同步和阻塞 在以后接触内核驱动 的时候会

loadrunner使用socket协议来实现客户端对服务器产生压力实例。(通过发送心跳包,达到连接多个客户端的目的)

#include "lrs.h" vuser_init(){ char *ip; int handler; //编写获取LR分配的Vuser IP函数,将IP保存在ip变量中. ip=lr_get_vuser_ip(); if(ip) lr_vuser_status_message("the ip address is %s:",ip); else lr_vuser_status_message("IP spooler disabled"); /

CentOS7.2 负载均衡层nginx-1.10.1增加sticky session模块支持

大家的网站都难免会遇到验证码的议题,前台后台的登入,都需要有验证码来做登入校验. 因为有些应用的验证码是在系统缓存中产生的,如果你使用的是负载均衡,那可能就会出现和我一样的情况:在验证验证码时,负载均衡在起着作用,用户访问的页面因在两台服务器间承接跳转的,会导致用户一直无法验证成功,所以在负载均衡上需要做sticky session支持,才能解决此问题. 所以我就要着手去处理这个问题. 安装环境及软件版本: 操作系统版本:CentOS 7.2 64bit 负载均衡层:nginx-1.10.1 服

AWS ELB Sticky Session有问题?别忘了AWSELB cookie

我们的产品中有两个Module,分别部署在独立的Linux机器上,Module 1需要向Module 2发起Http请求来获得服务.由于Module 2有多台,因此我们会在Module 2前部署一台负载均衡器(ELB,Elastic Load Balancer).我们部署在AWS里,因此使用的是AWS ELB. AWS ELB同时提供另一个很好的功能,叫做Sticky Session,它的作用是帮你把请求定向到其中一台机器,而非随机按ELB算法分散到其他机器.这样功能的好处是,如果我后一个请求依

[Unity Socket]在Unity中如何实现异步Socket通信技术

在刚刚开发Unity项目的过程中,需要用到即时通信功能来完成服务器与客户端自定义的数据结构封装. 现在将部分主要功能的实现代码抽取出来实现了可以异步Socket请求的技术Demo. 客户端脚本ClientScript /// <summary> /// Client Script. /// Created By 蓝鸥3G 2014.08.23 /// </summary> using UnityEngine; using System.Collections; public cla

Socket编程学习之道:揭开Socket编程的面纱

对TCP/IP.UDP.Socket编程这些词你不会很陌生吧?随着网络技术的发展,这些词充斥着我们的耳朵.那么我想问: 1.         什么是TCP/IP.UDP? 2.         Socket在哪里呢? 3.         Socket是什么呢? 4.         你会使用它们吗? 什么是TCP/IP.UDP? TCP/IP(Transmission Control Protocol/Internet Protocol)即传输控制协议/网间协议,是一个工业标准的协议集,它是为

socket技术详解(看清socket编程)

https://blog.csdn.net/weixin_39634961/article/details/80236161 socket编程是网络常用的编程,我们通过在网络中创建socket关键字来实现网络间的通信,通过收集大量的资料,通过这一章节,充分的了解socket编程,文章用引用了大量大神的分析,加上自己的理解,做个总结性的文章 1:socket大致介绍 socket编程是一门技术,它主要是在网络通信中经常用到 既然是一门技术,由于现在是面向对象的编程,一些计算机行业的大神通过抽象的理

socket 上传 -- 异常处理--UDP协议 --自定义socket #29

1.异常处理 1 '''''' 2 """ 3 异常处理 4 """ 5 """ 6 1.什么是异常? 7 程序在运行过程中出现了不可预知的错误,并且该错误没有对应的处理机制,就会以异常的形式表现出来 8 造成的影响就是整个程序无法再正常运行 9 """ 10 """ 11 2.异常的结构:类型+信息+位置 12 1.异常的类型:NAMEERROR 13 2