最近在使用Ratchet (一个PHP websocket框架)改造一个PHP网站的时候,出现了错误:

"It is set to 1024, but you have descriptors numbered at least as high as 1266.

--enable-fd-setsize=2048 is recommended, but you may want to set it
to equal the maximum number of open files supported by your system"

经过几番周折,发现原因是PHP源代码将FD_SIZE设置为1024了,一旦超过1024个websocket连接,就会报这个错。网上的解决方案,基本上是修改PHP源代码,重新编译PHP. 但是个人认为修改PHP源代码的做法存在风险,故我提出了新的思路,并在项目中成功运用(欢迎拍砖)。

基本原理是在后台多开几个websocket服务进程,每个进程用不同的端口号。而前台js随机连接后台开放的websocket服务进程端口号。这样每个websocket服务进程有1024的可用连接数,根据网站的峰值连接数计算可得所需开的websocket服务进程数量,当然需要留些余量。这样不需要重新编译PHP源代码,也能够轻松突破PHP websocket 1024个连接数限制了。

后台的实现


写一个push-server.php作为websocket服务, push-server的实现可以参照Ratchet的例子, 但是需要稍微改造下,即可以输入port作为命令行参数。

$port = $argv[1];
if ($port == ""){
$port = 40003; // 默认端口,如果启动push-server.php时不写参数,则使用40003端口
}
// .....省略其他代码 ..... // 将$port作为监听端口传入
$webSock->listen($port, '0.0.0.0');

  

根据需要,可以启动多个websocket进程,如:

php push-server 40003

php push-server 40004

php push-server 40005

这样后台就可以容许 1024 * 3 = 3072个websocket连接了。

前台的实现

随机获取连接服务的代码如下:

function getWSServer() {
var serverPorts = ['40003', '40004', '40005'];
var server = 'ws://youhost';
var randomPortIndex = Math.floor(Math.random() * serverPorts.length); server += ':' + serverPorts[randomPortIndex]; return server;
};

当然你也可以根据自己需要,指定什么时候连接某个websocket服务,不再赘述。

关于PHP Websocket 错误: "stream_select(): You MUST recompile PHP with a larger value of FD_SETSIZE" 的解决方案的更多相关文章

  1. webSocket错误收集

    关于 使用WebSocket报如下错误, Uncaught InvalidStateError: Failed to execute 'send' on 'WebSocket': already in ...

  2. Websocket————错误总结

    websocket 一.需要注意的是,js建立连接处完整的js代码要执行完成退出后才会真正发起建立连接请求,如果在此之前发送消息则会报错如下: InvalidStateError: An attemp ...

  3. mybatis(错误一) 项目启动时报“Result Maps collection already contains value forxxx”的解决方案

    Result Maps collection already contains value for xyx.dsw.dao.mapper.admin.quotationwish.TempTestTab ...

  4. IIS7虚拟目录出现HTTP错误500.19(由于权限不足而无法读取配置文件)的解决方案

    今天在window7上配置asp.net网站,但是访问总是提示 错误摘要HTTP 错误 500.19 - Internal Server Error无法访问请求的页面,因为该页的相关配置数据无效.详细 ...

  5. 命令行下运行 java someClass.class出现 “错误:找不到或无法加载主类someClass ” 的解决方案

    假设在C:\Java\code\目录下建立了如下 Test.java文件: package code; public class Test { public static void main(Stri ...

  6. 使用Git出现以下错误"Git@github.com: Permission denied (publickey). Could not read from remote repository."解决方案

    转载于:https://blog.csdn.net/dotphoenix/article/details/100130424 git@github.com: Permission denied (pu ...

  7. WCF错误远程服务器返回了意外响应: (413) Request Entity Too Large。解决方案

    这个问题出现的原因是  调用wcf服务的时候传递的参数 长度太大   wcf数据传输采用的默认的大小是65535字节. ---------------------------------------- ...

  8. eclipse 创建maven web错误Cannot change version of project facet Dynamic web module to 3.1解决方案

    Dynamic Web Module 选择“3.1”,java选择“1.8”,报错:Cannot change version of project facet Dynamic web module ...

  9. html websocket

    from:http://www.ibm.com/developerworks/cn/web/1112_huangxa_websocket/ websocket 规范升级过,在该链接的文章内未提及,后面 ...

随机推荐

  1. #maven解决乱码问题

    <build>        <plugins>        <plugin>        <groupId>org.apache.maven.pl ...

  2. Js 实现五级联动

    js实现多级联动的方法很多,这里给出⼀种5级联动的例子,其实可以扩展成N级联动,在做项目的时候碰到了这样⼀个问题但是有不能从数据库中动态的加载这些选项,所以只有想办法从单个的页面着手来处理了,应为项目 ...

  3. 控制语句(if-else+循环+switch)汇编规则

    [1]说说条件码 最常用的的条件码有: CF:进位标志 (无符号溢出) ZF:零标志 SF:符号标志(结果为负数) OF:溢出标志 (补码溢出, 有符号溢出) [2]有两类指令设置条件码而不改变任何其 ...

  4. IE浏览器部分版本不支持background-siza属性问题

    background-size是CSS3新增的属性,但是IE8以下还是不支持,可以通过滤镜来实现这样的一个效果 background-size:contain; // 缩小图片来适应元素的尺寸(保持像 ...

  5. Umbraco文档类型定义多个template

    利用这个可以同时写PC端和手机端的网站, 在Template中,建立手机端的模板: 在文档类型中,同时选择两个模板,在浏览的时候在URL后加上Template的名称 + .aspx 就可以浏览到你写的 ...

  6. hdu 4081 最小生成树+树形dp

    思路:直接先求一下最小生成树,然后用树形dp来求最优值.也就是两遍dfs. #include<iostream> #include<algorithm> #include< ...

  7. Miniui updateRow更改列字段值

    当UPC等于upccode时,更改列Scanned+1 //先grid.findRow找到UPC等于upccode的行对象 var row = grid.findRow(function (row) ...

  8. Android ViewPager

    昨天看到Weather&Clock Widget的页面滑动效果不错,了解了下可能是使用ViewPager来实现的,今天研究下,顺便记录下来.   根据Android官网的介绍,ViewPage ...

  9. 将ubuntu14.04设置为文本模式启动?

    修改改GRUB 的配置文件(不建议直接改 grub.conf) $sudo vim /etc/default/grub 找到: GRUB_CMDLINE_LINUX_DEFAULT="qui ...

  10. byte[] 清空

    1. using(byte buff = new byte[Size]){  // 你要用的代码,} 2. Array.Clear(bytes, 0 ,bytes.Length);