COMET 异步通知服务器关闭数据连接实现思路

在小编络络 COMET实践笔记一文中注意事项中有这么一段话

使用长连接时,
存在一个很常见的场景:客户端需要关闭页 面,而服务器端还处在读取数据的阻塞状态,客户端需要及时通知服务器端关闭数据连接。服务器在收到关闭请求后首先要从读取数据的阻塞状态唤醒,然后释放为
这个客户端分配的资源,再关闭连接。所以在设计上,我们需要使客户端的控制请求和数据请求使用不同的 HTTP 连接,才能使控制请求不会被阻塞。在实现上,如果是基于
iframe 流方式的长连接,客户端页面需要使用两个
iframe,一个是控制帧,用于往服务器端发送控制请求,控制请求能很快收到响应,不会被阻塞;一个是显示帧,用于往服务器端发送长连接请求。如果是基于 AJAX
的长轮询方式,客户端可以异步地发出一个 XMLHttpRequest 请求,通知服务器端关闭数据连接。

当初一直没想明白客户端要怎么样通知服务器端关闭数据连接,钻了牛角尖了,昨晚睡觉胡思乱想竟然给我想到一个方法,一大早起来就开始折腾了。

大致思路:页面(index.html)打开时挂起一个长连接(backend.php),需要关闭长连接时(如刷新页面时,本实验为了直观使用按钮点击)向服务器端发送一个异步关闭请求,服务器接收到关闭请求后在服务器上创建一个
close.txt 的关闭请求标识文件,在 backend.php 中检测有没有新消息的同时检测是否存在 close.txt 文件,如果存在 close.txt
文件则不管有没有取到消息都返回,index.html 根据返回的结果判断是主否主动关闭请求,如果是主动关闭请求则不再发起长连接。

实验文件:

index.html      首页,包含长连接请求,消息发送请求,关闭请求等内容

backend.php      后台消息获取文件,检查
data.txt 是否为空,及 close.txt 是否存在

writedata.php     获取客户端传来的消息,并将消息写入
data.txt 中

stop.php        接收客户端的半闭请求,并生成
close.txt 文件

1. index.html


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  
<head>
<title>Comet demo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script type="text/javascript" src="jquery.js"></script>
   
<script>
var comet = {
url:‘backend.php‘,
error:false,
stop:0,
connect : function(){
$.ajax({
url: comet.url,
type: ‘post‘,
dataType: ‘json‘,
timeout: 0,
success: function (response) {
comet.error = false;
comet.stop = response.stop ;
$("#content").append(‘<div>‘ + response.msg + ‘</div>‘);
},

error: function () {
comet.error = true;
},

complete: function () {
if (comet.error) {
setTimeout(function () {
comet.connect();
}, 5000);
} else {
              // 如果是主动关闭连接则不再发起请求
comet.stop ? ‘‘: comet.connect();
}
}
})
}
}

// 发送消息
function send_msg() {
var msg = $(‘#word‘).val();
$(‘#word‘).val(‘‘);
$.post(‘writedata.php‘,{‘msg‘: msg});
return false;
}

// 发送关闭请求
function close_commet() {
$.post(‘stop.php‘,function(res){
$("#content").append(‘<div>‘ + res + ‘</div>‘);
})
}

$(document).ready(function () {
//页面加载完毕创建长连接
comet.connect();
});
</script>
  
</head>
  
<body>
     
<div id="content"></div>

<p><form>
<input type="text" name="word" id="word" value=""/>       
<input type="button" name="send" onclick="send_msg();" value="发送"/>   
<input type="button" name="close" onclick="close_commet();" value="关闭长连接" />
</form>
</p>      
</body>
</html>

2. writedata.php


<?php

// 获取客户端消息,并存入 data.txt

$filename = ‘./data.txt‘;

$msg = isset($_REQUEST[‘msg‘]) ? $_REQUEST[‘msg‘] : ‘‘;

file_put_contents($filename, $msg);

3. stop.php


<?php
// 本文件用于接收到客户端异步关闭请求、
// 接收到关闭请求时应该想办法将该关闭请求让 backend.php 获取到
// 所以我们应该要将该关闭请求放到一个 backend.php 可以读取的空间,那么放到哪里呢
// cookie不行:因为 cookie 是存放在客户端的,发送关闭请求的时候,长连接已经建立,是获取不到关闭请求中创建的cookie的
// session也不行:backend.php 中由于处于阻塞状态,为了防止占用 session 我们在进入阻塞之前就关闭了 session 所以 session 也不行
// 最适合不过的无疑是 Memcache 了,当然数据库也行,这里为了简便,我们使用文件,当收到关闭请求时在服务器创建一个 close 文件,表示要关闭长连接
// backend.php 如果检测到存在 close 文件时不管有没有取到数据都返回

file_put_contents(‘./close.txt‘, ‘‘);

echo ‘接收到关闭请求‘;

?>

4. backend.php


<?php

//不限制超时时间
set_time_limit(0);

//在开启session的应用中这个函数非常重要,防止页面因session占用阻塞
session_write_close();

//用来存放数据的文件
$filename = ‘data.txt‘;

//读取文件内容
$content = file_get_contents($filename);

// 关断是否存在半闭请求
$close = file_exists(‘./close.txt‘);

// 如果 $content 为空,并且不存在关闭请求文件时阻塞等待
while ($content==‘‘ && !$close)
{
sleep(1);
$content = file_get_contents($filename);
$close = file_exists(‘./close.txt‘);
}

if ($close) {
$content = ‘长连接已关闭‘;
// 删除关闭请求标识文件
unlink(‘close.txt‘);
$response[‘stop‘] = 1;
} else {
//清空data.txt
file_put_contents($filename, ‘‘);
$response[‘stop‘] = 0;
}

// 返回消息
$response[‘msg‘] = $content;
echo json_encode($response);

?>

点击发送按钮之后:

点击关闭长连接之后:

相关代码下载:http://yun.baidu.com/s/1c0ovV6w

COMET 异步通知服务器关闭数据连接实现思路

时间: 2024-10-13 09:30:05

COMET 异步通知服务器关闭数据连接实现思路的相关文章

如何关闭android 4.4首次开机的移动数据连接

默认的android系统在第一次使用时,移动数据连接是自动打开的.如果你插有SIM卡,就会有走流量的情况.虽然在第一次使用时有设置向导会提示你是否要关闭数据连接,当你看到也会有些不爽:未经过我同意,移动数据竟然给打开了.你可能很快地关闭数据连接,但当你完成了设置后,再进到 设置->流量使用情况,可以看到移动数据产生了流量. 最近就是有这样的一个需求,在android4.4关掉系统默认的数据连接,结合网上查找资料,跟踪到ConnectivityService 类,位置是frameworks/bas

帆软报表学习之数据连接

帆软报表FineReport中数据连接的JDBC连接池属性问题 连接池原理 在帆软报表FineReport中,连接池主要由三部分组成:连接池的建立.连接池中连接使用的治理.连接池的关闭.下面就着重讨论这三部分及连接池的配置问题. 1. 连接池原理 连接池技术的核心思想,是连接复用,通过建立一个数据库连接池以及一套连接使用.分配.治理策略,使得该连接池中的连接可以得到高效.安全的复用,避免了数据库连接频繁建立.关闭的开销. 另外,由于对JDBC中的原始连接进行了封装,从而方便了数据库应用对于连接的

一个客户端向服务器发送数据,服务器向连接的客户端转发数据demo

服务端代码: // 负责处理每个线程通信的线程类 public class ServerThread implements Runnable { // 定义当前线程所处理的Socket Socket s = null; // 该线程所处理的Socket所对应的输入流 BufferedReader br = null; public ServerThread(Socket s) throws IOException { this.s = s; // 初始化该Socket对应的输入流 br = ne

使用OpenSSL做RSA签名验证 支付宝移动快捷支付 的服务器异步通知

由于业务需要,我们需要使用支付宝移动快捷支付做收款.支付宝给了我们<移动快捷支付应用集成接入包支付接口>见支付宝包<WS_SECURE_PAY_SDK>. 支付宝给的服务器demo只有Java.C#.PHP三种,而我们服务器端使用的是C++.这其中就涉及到接收支付宝的服务器异步通知.为了确保接收到的服务器异步通知来至支付宝,我们就必须验证支付宝的签名.坑爹的是,原来PC端使用MD5做签名,估计支付宝考虑到移动端的风险更高,于是改用RSA做移动快捷支付应用的签名.这无疑增加了我们迁移

支付宝手机网页即时到账接口(4)之交易接口服务器异步通知

前言 这篇文章主要讲诉系统调用支付宝手机网页即时交易接口后支付宝返回的异步通知. 支付宝对商户的请求数据处理完成后,会将处理的结果数据通过服务器主动通知的方式通知给商户网站.这些处理结果数据就是服务器异步通知参数. 特性 必须保证服务器异步通知页面(notify_url)上无任何字符,如空格.HTML标签.开发系统自带抛出的异常提示信息或错误页面等. 支付宝是用POST方式发送通知信息,因此该页面中获取参数的方式,如: request.Form("out_trade_no").$_PO

Android开发中数据连接的开启和关闭

最近在做Android开发的过程中,我想要通过代码来实现数据连接的开启和关闭,最初我将目标锁定为ConnectivityManager类,但是在翻阅了Android官方API后并没有找到相关的方法,如图1. 图1 但是据说Android的一些类的某些方法的API是非公开的,所以我又做了如下尝试,获得ConnectivityManager在加载时的Class对象,并查看了其中的方法,代码如下: 1 ConnectivityManager connectivityManager = null; 2

支付宝接口使用文档说明 支付宝异步通知(notify_url)与return_url

原文:http://blog.csdn.net/m13666368773/article/details/6888513/ 支付宝接口使用文档说明 支付宝异步通知(notify_url)与return_url. 现支付宝的通知有两类. 1-服务器通知(支付宝通知我们的服务器),对应的参数为notify_url,支付宝通知使用POST方式 2-页面跳转通知(支付成功后,从支付宝跳转到指定的地址),对应的参数为return_url,支付宝通知使用GET方式 (通知地址不需要像以前一样去账户内设置,而

支付宝异步通知notify_url与return_url

支付宝接口使用文档说明 支付宝异步通知(notify_url)与return_url. 现支付宝的通知有两类. A服务器通知,对应的参数为notify_url,支付宝通知使用POST方式 B页面跳转通知,对应的参数为return_url,支付宝通知使用GET方式 (通知地址不需要像以前一样去账户内设置,而是由客户在支付的时候通过参数传递给我地址. 例如 notify_url=http://www.xxx.com/notify_alipay.jsp 注意:www.XXX.com是您网站的域名,也可

深入理解Tornado——一个异步web服务器

本人的第一次翻译,转载请注明出处:http://www.cnblogs.com/yiwenshengmei/archive/2011/06/08/understanding_tornado.html原文地址:http://golubenco.org/?p=16 这篇文章的目的在于对Tornado这个异步服务器软件的底层进行一番探索.我采用自底向上的方式进行介绍,从轮巡开始,向上一直到应用层,指出我认为有趣的部分.所以,如果你有打算要阅读Tornado这个web框架的源码,又或者是你对一个异步we