我有一个 Node websockets 服务器,所有设置都带有运行良好的聊天服务。但我希望 LAMP 服务器能够定期向连接到 websocket 服务器的用户发送消息。 (响应用户浏览器操作或 cron 作业)。所以我需要一些 PHP 代码来向 Node 服务器发送请求(都在 Google Compute Engine 上)。
我通过这个答案找到:https://stackoverflow.com/a/22411059/947374 ...指向论坛的链接,有人在其中很好地解决了这个问题:https://forum.ripple.com/viewtopic.php?f=2&t=6171&p=43313#p43313
我的 PHP 代码现在看起来像:
//local address of node server
$host='XXX.XXX.XXX.XXX';
$port=80;
//location where THIS script is running FROM
$local="http://localhost";
//json the data to send
$data=json_encode($data);
//some very particular headers
$head = "GET / HTTP/1.1"."\r\n".
"Upgrade: WebSocket"."\r\n".
"Connection: Upgrade"."\r\n".
"Origin: $local"."\r\n".
"Host: $host"."\r\n".
"Sec-WebSocket-Version: 13"."\r\n".
"Sec-WebSocket-Key: asdasdaas76da7sd6asd6as7d"."\r\n".
"Content-Length: ".strlen($data)."\r\n"."\r\n";
//WebSocket handshake
$sock = fsockopen($host, $port, $errno, $errstr, 2);
fwrite($sock, $head ) or die('error:'.$errno.':'.$errstr);
$headers = fread($sock, 2000);
//see the second link above for what hybi10Encode() is doing
fwrite($sock, hybi10Encode($data)) or die('error:'.$errno.':'.$errstr);
$wsdata = fread($sock, 2000);
fclose($sock);
数据从 PHP 发送到 Node 。美丽的。赞美主。
唯一的问题是连接似乎保持打开状态大约 60 秒。数据立即从 PHP 发送到 Node ,网络聊天立即响应,就像我想要的那样。但是请求 PHP 脚本的浏览器选项卡会旋转 60 秒,并且在第一个请求完成之前不会接受另一个请求。
我原以为包含 fclose() 会使连接不会像这样保持打开状态。
我还尝试将 header 更改为: 连接:关闭 和/或尝试过 获取/HTTP/1.0 (根据具有类似问题的其他线程的一些建议)这也没有帮助。
关于如何让 PHP 脚本立即关闭连接或让 Node 服务器在处理完请求后立即断开与 LAMP 服务器的连接,有什么建议吗?
最佳答案
你真的到达了fclose()吗?
如果代码处于阻塞模式 (http://php.net/manual/en/function.stream-set-blocking.php) 并且不发送 2000 字节或 eof - 换句话说,代码可能会卡在 fread() 上fread 会超时。
测试:
- 把 echo 'Closing'; 放在 fclose 之前,这样你就知道你到了那里
- 添加 stream_set_blocking ($sock, false);
- 缩短套接字超时(http://php.net/manual/en/function.stream-set-timeout.php)
小警告:如果你设置了非阻塞,你可能需要循环 $headers = fread($sock, 2000); 因为它会立即返回,即使没有数据存在。创建一个 while 循环,它会一直循环直到您手动超时,否则您会得到预期的响应。
关于php - fsockopen 连接保持打开状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41706204/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以
当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested
我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
我想为我的Task模型创建一个status属性,该属性将按以下顺序指示它在三部分进度中的位置:打开=>进行中=>完成。它的工作方式类似于亚马逊包裹的交付方式:已订购=>已发货=>已交付。我想知道设置此属性的最佳方法是什么。我可能是错的,但创建三个独立的bool属性似乎有点多余。实现此目标的最佳方法是什么? 最佳答案 Rails4有一个内置的enummacro.它使用单个整数列并映射到键列表。classOrderenumstatus:[:ordered,:shipped,:delivered]end状态映射如下:{ordered:0,
我有这个代码File.open(file_name,'r'){|file|file.read}但是Rubocop发出警告:Offenses:Style/SymbolProc:Pass&:readasargumenttoopeninsteadofablock.你是怎么做到的? 最佳答案 我刚刚创建了一个名为“t.txt”的文件,其中包含“Hello,World\n”。我们可以按如下方式阅读。File.open('t.txt','r',&:read)#=>"Hello,World\n"顺便说一下,由于第二个参数的默认值是'r',所以这样
s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成