Comet初步研究与实践 – PHP到C#应用程序的数据推送DEMO
前段时间小接触了一下comet,关于其基本原理和代码示例请参考我之前的博文《与comet的一次亲密接触——基于ajax的http的长连接技术》
这次我们稍微系统的实现一个由PHP Web 服务器端向一个C#客户端应用程序推送的示例。实现“推送”、“用户状态”、“用户列表”的功能。具体一些代码细节就不详细介绍了,主要拿出几个关键问题来与大家分享和讨论。
本文不讨论复杂的comet框架,只从最基本的ajax长连接实现层面来构建应用。若有兴趣研究pushlet等comet框架的朋友请自行研究。
1. 数据传输流程。
应用程序 -> 内嵌webbrowser -> javascript -> ajax后台 -> Web服务器抓住请求 -> Web服务放开请求并附带数据 -> json数据流 -> javascript -> 应用程序
使用C#内嵌的一个WebBrowser 访问一个页面来启动我们的长连接。(因为我不想与平台进行太多的绑定,所以尽量把所有的数据传输层全部放在WEB上来做,下同,不再解释。)
Web服务器收到后抓住请求,直到需要推送数据,则放开属于该客户端的请求。打成json发回,然后javascript回调C#绑定的函数,将数据传送到应用程序中。
2. Web服务器如何“抓住请求”和“识别客户端”?
抓住请求,毫无疑问——使用轮询。
网上有comet的示例聊天室代码是轮询一个文件,我之前的博客中也是用轮询文件实现的。不管是轮询文件、管道、或者在数据库上轮询都是效率较低的。这里我使用 Linux的共享内存,相当于在PHP里有了常驻变量。
对于每个用户,长连接上来的时候都发送一个用户ID。然后我们PHP在共享内存中维护一张用户ID表。用这个ID表来维护所有到服务器的comet连接。
3. 如何“放开请求”?
即轮询何时结束——
我这儿实现是轮询共享内存,客户端找到自己ID对应的内存位置,不断轮询,直到有新的数据。所以很显然,必须存储推送数据内容、数据更新时间 和对应用户ID。(若想采用任务队列或者订制等策略也都可以在这里做。)那么,轮询就很简单:
while( $curr_time == $last_time )
{
usleep(1000000);
clearstatcache();
$data = user_fetch_data($id);
$curr_time = $data->timestamp;
}
直到有新的数据,就推送给该用户。
可能有人要问,为什么不直接就用一个数据字段呢?来了数据就把它“取走”(拿出来并且删掉),直到有数据就放开连接。——这样的想法很朴素,也是很容易第一点想到的。但是有个问题就是若客户端同一个ID重复comet连接,就会造成对该资源竞争,几个进程轮询同一个数据,当数据来了,被其中一个取走,其他的就取不到了……
可能你又要说,我不让一个id重复登录不就可以了么?
——这里很难控制,若用户刷新页面,之前那个长连接没有释放,又上来一个,就会存在一个“废物轮询进程”和自己竞争了。或者网络情况不好,用户断了,重新连接(这个场景还是会经常出现的),也会产生“废物轮询进程”。
所以这儿用时间戳作为轮询出口,还是能避免这种竞争问题的。
4. 如何知道用户下线?
没辙,为了简单实现,我只想到心跳包。因为浏览器的关闭我们在服务器端无法即时知晓,而我也不想在C#中做截获消息来实现。(原因同1,咱的应用完全独立于终端平台也要能做,不和平台绑定)
直接在数据库user表上做操作,
mysql> select * from user;
+----+--------+---------------------+
| id | status | updatetime |
+----+--------+---------------------+
| 1 | 1 | 2010-05-27 15:28:41 |
| 2 | 0 | 2010-05-27 14:08:21 |
| 3 | 0 | 2010-05-27 09:59:41 |
+----+--------+---------------------+
3 rows in set (0.00 sec)
我这里实现用的每5秒心跳包,服务器每20秒检测。基本还是好使的。
心跳包和comet的启动可以做到一起,都在访问的这个页面中,可以使用javascript定时器调用ajax给服务器发送心跳。
setInterval("heartbeat();",5000)
查询用户状态就简单了。直接在数据库上select就行了。
5. 推送数据如何发送到C#来?
C#的WebBrowser中ObjectForScripting可以暴露C#中一个Object给javascript,注意Object需要标记ComVisible。直接调用就可以了,示例代码如下:
[System.Runtime.InteropServices.ComVisible(true)]
public partial class Form1 : Form
{
static private string WebRoot = "http://192.168.25.152/comet/";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string userid = textBox4.Text;
webBrowser1.Url = new Uri(WebRoot + "user_comet.php?id=" + userid);
webBrowser1.ObjectForScripting = this;
}
public void HandleData(string data)
{
//处理数据
}
}
Javascript直接用window.external就可以拿到该对象句柄。
Javascript代码:
window.external.HandleData(data);
最后,极度郁闷,本来这文章都写完了。Csdn这个页面莫名其妙的刷新了一下,@!#@#%#¥%于是我又重新写了一遍,崩溃中……
展示一下写的个简单测试工具的运行结果。上面部分是收到推送的数据。
下面发送指令和反馈数据是对Web服务器的操作。可以通过XML发送指令,控制推送
分享到:
相关推荐
总的来说,这个"comet demo"是一个学习和理解Comet技术的绝佳实践,可以帮助开发者掌握如何在Java Web环境中实现服务器向客户端的实时数据推送。通过深入研究和运行这个示例,你可以更好地了解HTTP长连接的工作原理...
在IT行业中,消息推送是一项关键的技术,特别是在实时通信和交互性应用中...通过深入研究这些源码,开发者不仅可以掌握C#中的消息推送技术,还能了解到如何将这些技术应用于实际项目,提升应用程序的实时性和用户体验。
Comet4j是一个Java库,专门用于实现服务器向客户端的实时推送技术,它...通过这个Demo,开发者可以学习到如何在实际项目中应用Comet4j,掌握服务器推送的关键技术和实践方法,为构建高性能、实时的Web应用打下基础。
Comet 是一种网络技术,它颠覆了传统的HTTP请求与响应模型,使得服务器能够主动向客户端推送数据,而不仅仅是在客户端发起请求时才进行交互。这种技术对于实现实时性极强的在线应用,如聊天室、股票报价、在线游戏等...
2. **事件驱动模型**:Comet4j 使用事件驱动的编程模型,服务器端接收到新数据后,会触发相应的事件,将消息推送到客户端。 3. **高性能设计**:Comet4j 设计时考虑了性能优化,如连接池管理、线程池调度等,确保在...
先进入login.jsp通过名字登陆,然后可以发邮件一个框输内容一个框输想收件人id
Comet技术为Web即时通讯提供了一个有效的解决方案,通过C#的Comet框架,开发者可以更轻松地实现服务器到客户端的数据推送。自定义扩展功能进一步增强了框架的灵活性,使其能适应各种复杂的业务需求。结合提供的...
【Comet4j完整demo】是一个演示项目,它展示了如何使用Comet4j技术与Tomcat7集成,实现高效的服务器推送消息功能。Comet4j是一个开源的Java库,专门设计用于处理长连接(Long-Polling)通信,从而允许服务器主动向...
- 在这个"Comet的demo"中,可能使用了上述的一种或多种技术来实现长连接和数据推送。具体实现方式可以通过分析代码和运行示例来了解。 5. **文件分析**: - "Comet"这个压缩包中的文件可能是服务器端代码(例如用...
javaweb消息推送 基于comet实现局域网内部通讯(聊天室)demo 功能特性 推送消息广播。 推送定向消息。 提供连接上线前、上线、下线前、下线、发送消息等多种可处理事件。 消息缓存机制,确保长轮询工作模式下不丢失...
总结来说,"web推送 Comet技术"利用了Comet4J框架和Tomcat7服务器,实现在Web应用中的实时数据推送。它挑战了传统的HTTP交互方式,提升了用户体验,但同时也带来了额外的系统管理和优化挑战。在开发过程中,理解...
`comet4j`是一种基于Java的服务器端消息推送技术,它允许服务器主动向客户端发送数据,而无需客户端频繁发起请求,从而提高了Web应用程序的实时性。在传统的HTTP协议中,服务器通常只能在客户端发起请求时响应,而...
5. **测试用例**:Test_comet可能是测试脚本或者一个简单的应用程序,用于验证Comet4j服务器推送功能是否正常工作。你可以通过运行这个测试用例,观察服务器和客户端之间的通信,以确保配置正确。 在学习和使用这个...
Java 使用 Comet4j 主动向客户端推送信息是一个常见的实时通信技术,主要应用于构建WebSocket或长轮询等实时交互的应用场景。Comet4j 是一个基于 HTTP 长连接的服务器端框架,它允许服务器端主动向客户端推送数据,...
本示例介绍的是如何使用Comet4j这个第三方库来实现后台到前台的消息推送功能。Comet4j是一个专门用于JavaWeb应用的长连接通讯框架,它简化了基于Comet技术的实时通信实现。 首先,我们要理解Comet技术。Comet是一种...
Comet是一种Web应用程序架构,用于创建持久连接,允许服务器向客户端(通常是浏览器)实时推送数据。在传统的HTTP协议中,服务器只能在客户端发起请求时发送数据,而Comet通过长时间保持一个HTTP连接开放,使得...
PHP防Sina微博无刷新服务器推送(Comet)原理是一种技术策略,用于实现在Web应用中实现长轮询或持久连接,使得服务器可以主动向客户端推送数据,而无需客户端频繁发送请求。这种技术在实时性要求较高的场景下,如...
了解并掌握"Dwr2推送Demo"的实现原理和步骤,对于理解DWR2的Push功能以及如何在实际项目中应用Ajax实时推送技术非常有帮助。此外,这也能为开发者提供一个基础,以便进一步探索更先进的Web实时通信技术,如WebSocket...
实现Comet消息推送功能,根据登陆人定向推送,解决刷新页面原有ScriptSession不能及时销毁的问题,DEMO比较简陋,请先进入login.jsp页面登陆。根据登陆名称判断推送目标,可登陆多个用户进行测试。
在本文中,我们将深入探讨如何...通过在后端处理数据推送和前端与服务器的交互,可以构建出高性能、低延迟的实时Web应用。开发者在实际应用中,需根据项目需求选择合适的Comet实现方式,并考虑性能优化和扩展性设计。