我知道使用普通的线程网络服务器(例如Apache)进行AJAX长轮询是不好的设计......但我真的不明白为什么.
是因为每个longpolling请求比正常请求花费的时间要多得多(从而占用处理器)?如果是这种情况,那么线程是否真的需要花费很多开销才能在使用之前保持闲置一段时间?
我需要找出一个可以随时改变的对象的状态.最好的情况是,如果对象发生变化,客户端会更新,但是我认为没有管道可以将更新推送到客户端而没有客户端首先要求它.
所以,我正在考虑通过jQuery ajax调用来实现轮询,该调用每5秒左右设置一次呼叫服务器.这是合理的解决方案吗?
我在一个使用jQuery ajax的函数中做了一个像轮询一样的长轮询,它将一直运行.还有另一个请求将数据发送到PHP后端文件,而第二个请求不是长轮询,它只是将数据发送到该PHP文件.
问题:我用Firebug检查过,当长轮询请求运行时,只要长轮询正在运行,我就无法发送另一个请求.即使长轮询正在运行,如何发送另一个请求?
注意:我用过async: true两者.
另一个问题:如何确保即使是持有长轮询请求代码的函数也会被多次调用,但长轮询请求只会被调用,只有一个?
我正在使用带有集线器的SignalR 0.5.3,我明确地将传输设置为长轮询,如下所示:
$.connection.hub.start({ transport: 'longPolling' }, function () {
console.log('connected');
});
Run Code Online (Sandbox Code Playgroud)
使用这样的配置(在global.asax.cs Application_Start方法中):
GlobalHost.DependencyResolver.UseRedis(server, port, password, pubsubDB, "FooBar");
GlobalHost.Configuration.DisconnectTimeout = TimeSpan.FromSeconds(2);
GlobalHost.Configuration.KeepAlive = TimeSpan.FromSeconds(15);
Run Code Online (Sandbox Code Playgroud)
然而,长期轮询似乎既不适用于开发(IIS express)也不适用于生产(IIS 7.5)环境.连接似乎正常,但长轮询请求总是超时(约2分钟后),之后重新连接.IIS的日志在这里.第一次超时请求的回复:
{"MessageId":"3636","Messages":[],"Disconnect":false,"TimedOut":true,"TransportData":{"Groups":["NotificationHub.56DDB6692001Ex"],"LongPollDelay":0}}
Run Code Online (Sandbox Code Playgroud)
超时重新连接响应如下所示:
{"MessageId":"3641","Messages":[],"Disconnect":false,"TimedOut":true,"TransportData":{"Groups":["NotificationHub.56DDB6692001Ex"],"LongPollDelay":0}}
Run Code Online (Sandbox Code Playgroud)
对于这个问题,我将不胜感激.谢谢.
编辑
如果重新连接意味着新的长轮询周期的开始,为什么在global.asax.cs中的KeepAlive设置设置为15秒后~2分钟后启动?问题在于我在IIS前面有一个反向代理,它在25秒后超时保持活动请求,因此当达到此反向代理超时时,我得到504响应.
我的理解是,在Tomcat中,每个请求将占用一个Java /(以及OS)线程.
想象一下,我有一个应用程序有很多长期运行的请求(例如一个有多个玩家的扑克游戏),涉及游戏内聊天和AJAX长轮询等.
有没有办法改变我的webapp的tomcat配置/架构,这样我就不会为每个请求使用一个线程,而是"拦截"请求和响应,以便它们可以作为队列的一部分进行处理?
我正在尝试实现一个全局按钮计数器,可以在任何/不同用户单击它时进行更新.所以我的想法是,如果一个人点击按钮,我会看到我的页面实例上的计数器更新.
我目前使用长轮询技术,或者我认为,但经过审核后,我认为我将错误"广播"到所有浏览器的更新.
目前的错误是,如果我打开了两个浏览器,并且我不断点击一个浏览器,那么我点击该按钮的浏览器只会更新一半时间.它将获得1 3 5等,而另一个浏览器显示2 4 6等.
在线查看后,我认为这可能与频道和广播到网站上的所有浏览器有关.如果有人可以帮我提供一个如何将更新发送到所有浏览器的示例,那么每次,我都非常感激.
客户:
<html>
<script language=javascript>
function longpoll(url, callback) {
var req = new XMLHttpRequest ();
req.open ('GET', url, true);
req.onreadystatechange = function (aEvt) {
if (req.readyState == 4) {
if (req.status == 200) {
callback(req.responseText);
longpoll(url, callback);
} else {
alert ("long-poll connection lost");
}
}
};
req.send(null);
}
function recv(msg) {
var box = document.getElementById("counter");
box.innerHTML += msg + "\n";
}
function send() {
var box = document.getElementById("counter");
var req = new …Run Code Online (Sandbox Code Playgroud) 目前,我已经在node.js中创建了一个应用程序,使用带有mysql的socket.io向所有客户端发送通知.因此,我的mysql数据库中的任何更改都将立即通过socket.io通知多个客户端.应用工作的魅力.
我面临的问题与性能问题有关.
我的浏览器从服务器获得持续推送通知,这会降低浏览器的性能.I/Client需要仅在数据库更改时获取通知,其余时间服务器应处于暂停状态,而不向cilent发送任何消息.
换句话说,我需要实现长轮询技术.
如何使用socket.io实现长轮询?
我用Google搜索了一个例子,但我发现没有任何可以帮助我在node.js中用socket.io和mysql实现长轮询
是否可以使用socket.io实现长轮询?
如果是这样,有人可以通过示例将我重定向到一些有用的链接吗?
提前致谢.
我正在尝试使用长轮询构建一个laravel聊天应用程序(我知道有nodejs/redis但是有问题)因此我一直在尝试将这个示例实现到Laravel和MySQL中.
然而,AJAX GET状态请求始终坚持的pending....我想这可能是因为它没有更新div,我从同一页面上的AJAX POST请求显示新输入的新值.目前,div仅在刷新时自行更新.
这是我的代码:
视图
function getMsg(timestamp){
var queryString = {"timestamp":timestamp};
$.get(
"create",
queryString,
function(data){
var obj = $.parseJSON(data);
console.log(obj.timestamp);
$('#response').append('<p>'+obj.body+'</p>');
getMsg(obj.timestamp);
}
).fail( function(xhr, textStatus, errorThrown) {
alert(xhr.responseText);
});
}
getMsg();
Run Code Online (Sandbox Code Playgroud)
调节器
public function create()
{
$Msg = new Chatting;
if(Request::ajax()){
set_time_limit(0);
session_write_close();
while(true){
$last_ajax_call = isset($_GET['timestamp'])?(int)$_GET['timestamp']:null;
clearstatcache();
$last_timestamp = $Msg->select(array('created_at'))->orderBy('created_at','desc')->first();
$last_change = json_decode($last_timestamp);
if($last_ajax_call == null || $last_change->created_at > $last_ajax_call){
$result = array(
'body'=> $Msg->select('body','created_at')->where('created_at','=',$last_change->created_at)->first()->body,
'timestamp'=> $last_change->created_at …Run Code Online (Sandbox Code Playgroud) 我正在尝试在Java Web应用程序中实现长轮询.该应用程序是使用Spring MVC 3.2编写的,我使用了DeferredResult对象(它代表了Servlet 3.0异步响应功能).
问题是当使用DeferredResult时,每次发送请求10秒后我都会收到内部服务器错误(代码500).预期结果是30秒后的文本数据.我的应用程序日志中没有任何内容,Tomcat日志中没有任何内容,但在FireFox网络监视器中,我看到此错误.
另一方面,当我发送同步请求并在服务器中保持30秒时,它成功完成.
谁能帮我这个?
本文末尾有一个测试应用程序下载链接.这是一个maven应用程序.
这是我的应用代码:
ResponseController.java
@Controller
@RequestMapping("responses")
public class ResponseController {
@Autowired
private ResponseService messagesService;
@RequestMapping(value="/async", method=RequestMethod.GET)
@ResponseBody
public DeferredResult<String> getAsyncUpdate() {
return messagesService.getAsyncUpdate();
}
@RequestMapping(value="/sync", method=RequestMethod.GET)
@ResponseBody
public String getSyncUpdate() {
return messagesService.getSyncUpdate();
}
}
Run Code Online (Sandbox Code Playgroud)
ResponseService.java
@Service
public class ResponseService {
private DeferredResult<String> deferredResult;
public DeferredResult<String> getAsyncUpdate(){
deferredResult = new DeferredResult<String>();
return deferredResult;
}
public String getSyncUpdate(){
long startTime = System.currentTimeMillis();
while( System.currentTimeMillis() - startTime <30000){
}
return "RESULT";
}
@Scheduled(fixedDelay=500)
public void …Run Code Online (Sandbox Code Playgroud) 您是否愿意分享任何最新的手册,或者在这里解释如何用最新的Spring(Spring Boot)实现REST Long Polling端点?
到现在为止,我发现的所有内容都已经过时,并且是几年前发布的。
因此,我提出一个问题,长轮询仍然是一种好方法吗?我知道国际象棋使用了它
long-polling ×10
ajax ×3
asp.net ×2
java ×2
mysql ×2
php ×2
spring-mvc ×2
ajax-polling ×1
asp.net-mvc ×1
event-loop ×1
go ×1
javascript ×1
jquery ×1
laravel-4 ×1
node.js ×1
request ×1
rest ×1
signalr ×1
signalr-hub ×1
socket.io ×1
spring-boot ×1
tomcat ×1
tomcat7 ×1