WebIM(4)----Comet的特殊之处
在一步一步打造WebIM(1)一文中已经使用Comet实现了一个简单的WebIM,那么,Comet究竟和一般的打开网页有何区别,本文将通过编写一个简单的HTTP服务器来说明两者的区别。
所谓网站,其实可以理解为服务器上的一个应用程序,该应用程序创建了一个Socket并在80端口(一般是80端口)上监听,并接受和处理浏览器发送过来的HTTP请求。
当你打开网页时,浏览器会发送一个HTTP请求到服务器,之后浏览器将一直等待知道服务器发送完HTTP回应。当服务器接受到这个http请求后,就会解析HTTP请求的头部,根据报文中的信息向浏览器发送数据(网页,图片,数据等),当服务器发送完数据后,浏览器就结束等待,显示出网页。关于浏览器和服务器之前的交互,可以阅读这篇博文:
HTTP协议及其POST与GET操作差异 & C#中如何使用POST、GET等
根据以上叙述的交互过程,可以编写一个简单的http服务器,该服务器在8000端口监听,并且只提供两个网页
http://localhost:8000/index.htm
http://localhost:8000/comet.htm
这两个网页的区别在于,index.htm服务器在接收到HTTP请求后立刻发送网页并结束本次链接,而Comet.htm则不是如此,是将链接先挂起,并启动一个线程,新的线程将延迟5秒再发送网页。服务器源代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using System.Net;
using System.Net.Sockets;
using System.Threading; namespace http
{
class Program
{
static String ResponeFormat =
"HTTP/1.1 200 OK\r\n" +
"Content-Length: {0}\r\n" +
"Connection: close\r\n" +
"Content-Type: text/html\r\n" +
"\r\n" +
"{1}\r\n"; static void Main(string[] args)
{
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //在8000端口监听
EndPoint ep = new IPEndPoint(new IPAddress(new byte[] { 127, 0, 0, 1 }), 8000);
server.Bind(ep);
server.Listen(5); while (true)
{
Socket client = server.Accept(); //读取HTTP报文头部
String header = String.Empty;
while (header.IndexOf("\r\n\r\n") < 0)
{
byte[] buffer = new byte[1024];
int len = client.Receive(buffer);
header += Encoding.ASCII.GetString(buffer, 0, len);
} Console.WriteLine("================================================================================");
Console.Write(header); Regex reg = new Regex(@"GET\s+([^\s\r\n]+)\s+HTTP/1.1\s*\r\n", RegexOptions.IgnoreCase);
Match match = reg.Match(header);
if (match.Success)
{
String fname = Path.GetFileName(match.Groups[1].Value).ToLower(); if (fname == "index.htm")
{
String html = String.Format("<span style='color:red; fonst-size:24px;'>{0}</span>", DateTime.Now);
String response = String.Format(ResponeFormat, html.Length, html); //发送HTTP回应,本次HTTP请求结束,浏览器将立刻接受到网页
client.Send(Encoding.UTF8.GetBytes(response));
client.Close();
}
else if (fname == "comet.htm")
{
//假设此时数据未准备好,先挂起链接,网页将在另一个线程中发送到浏览器
//在线程没有发送HTTP回应前,浏览器将一直等待,直到启动的线程发送回应
Thread thread = new Thread(new ParameterizedThreadStart(SendThreadEntry));
thread.Start(client); }
else
{
client.Close();
}
}
}
} static void SendThreadEntry(object data)
{
//等待5s
Thread.Sleep(5000);
Socket client = data as Socket;
String html = String.Format("<span style='color:red; fonst-size:24px;'>{0}</span>", DateTime.Now);
String response = String.Format(ResponeFormat, html.Length, html); Console.WriteLine("Send Response"); //发送HTTP回应,本次HTTP请求结束,浏览器此时才接收到网页,在此之前浏览器一直等待
client.Send(Encoding.UTF8.GetBytes(response));
client.Close();
}
}
}
当然,发送Comet.htm的数据不一定启动一个新的线程,可以先将client保存起来(例如保存到全局变量中),等数据准备好了,调用client的Send方法发送数据。
本文来自:http://www.cnblogs.com/lucc/archive/2010/05/25/1743877.html
WebIM(4)----Comet的特殊之处的更多相关文章
- 浅入浅出“服务器推送”之一:Comet简介
最近有个项目,其中有项需求要从服务器端主动向客户端推送数据,本以为很简单,但在实际做的过程中发现很棘手,并没有想象中的简单.从网上搜索学习,发现主流讲的还是Ajax的长轮询技术或者流技术,websoc ...
- comet在asp.net中的实现
网上有关“服务器推送”的介绍非常多,其中一种实现方式就是采用comet技术,在浏览器与服务端之间建立一个http协议的“长连接”,所谓“长连接”,就是指浏览器到服务端的http请求不会马上得到服务端的 ...
- js021-Ajax与Comet
js021-Ajax与Comet 本章内容: 使用XMLHttpRequet对象 使用XMLHttpRequet事件 跨域Ajax通信的限制 Ajax技术的核心是XMLHttpRequet对象 21. ...
- Comet:基于 HTTP 长连接的“服务器推”技术解析
原文链接:http://www.cnblogs.com/deepleo/p/Comet.html 一.背景介绍 传统web请求,是显式的向服务器发送http Request,拿到Response后显示 ...
- 反向Ajax,实现服务器向客户端推送消息之 Comet
基于 HTTP 长连接.无须在浏览器端安装插件的“服务器推”技术为“Comet”. 下面将介绍两种 Comet 应用的实现模型. 基于 AJAX 的长轮询(long-polling)方式 AJAX 的 ...
- Comet:基于 HTTP 长连接的“服务器推”技术
“服务器推”技术的应用 请访问 Ajax 技术资源中心,这是有关 Ajax 编程模型信息的一站式中心,包括很多文档.教程.论坛.blog.wiki 和新闻.任何 Ajax 的新信息都能在这里找到. c ...
- Comet技术详解:基于HTTP长连接的Web端实时通信技术
前言 一般来说,Web端即时通讯技术因受限于浏览器的设计限制,一直以来实现起来并不容易,主流的Web端即时通讯方案大致有4种:传统Ajax短轮询.Comet技术.WebSocket技术.SSE(Ser ...
- comet
comet 1.简介: 基于 HTTP长连接的“服务器推”技术,是一种新的 Web 应用架构,基于这种架构开发的应用中,服务器端会主动以异步的方式向客户端程序推送数据,而不需要客户端显式的发出请求.C ...
- WEB实时聊天 comet推技术
转自:http://www.cnblogs.com/wodemeng/archive/2012/04/06/2435302.html 今天晚上朋友遇到web服务端推技术的问题,自己就查了下资料,学习了 ...
随机推荐
- 使用PF_PACKET和SOCK_RAW发送自己定义type以太网数据包
本文介绍使用PF_PACKET和SOCK_RAW发送自己定义type以太网数据包,使用wireshare抓包能够获取到数据包,为Linux内核添加网络协议做铺垫. 先上码: #include < ...
- C#中假设正确使用线程Task类和Thread类
C#中使用线程Task类和Thread类小结 刚接触C#3个月左右.原先一直使用C++开发.由于公司的须要,所地採用C#开发.主要是控制设备的实时性操作,此为背景. 对于C#中的Task和Thread ...
- JavaEE(18) - JPA原生SQL查询和存储过程
1. 使用原生SQL执行查询 2. 映射原生SQL查询的结果集 3. 使用原生SQL查询执行实体查询 4. 命名原生SQL查询 5. 在JPQL查询中调用存储过程
- Html.Partial和Html. RenderPartial用法
Html.Partial和Html. RenderPartial用法 Html.partial和RenderPartial的用法与区别Html.partial和RenderPartial都是输出htm ...
- 【 D3.js 入门系列 --- 9.1 】 生产饼图
我个人的博客: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处.谢谢. 这一节用 Layout 做一个饼状图.第9节中说过, Layout ...
- 第4章 建造者模式(Builder Pattern)
原文 第4章 建造者模式(Builder Pattern) 定义 将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式. 实用范围 1 当创建复杂对象 ...
- C语言中符号格式说明
scanf 语法: #include <stdio.h>int scanf( const char *format, ... ); scanf()函数根据由format(格式)指定的格式从 ...
- 在LINQ中实现多条件联合主键LEFT JOIN
我昨天遇到一个LINQ下使用多条件比对产生LEFT JOIN的问题,经过深入研究,终于解决了,也让我学到了新的东西,特地拿来分享. 实例:有一张库存异常变更视图KCYD,仓库ID[Ckid]和物品ID ...
- Android开发之控制Toast的开启与关闭
开发这个程序之前先解释一下,为什么Toast信息提示框在显示一定时间后会自己主动消失?由于在Android系统中有一个Toast队列,系统会依次从这个队列中取出一个Toast,并显示它.在显示了指定时 ...
- Robot Framework + appium 启动手机浏览器的两个方法(1)
一.Open Browser启动 使用Selenium2Library的Open Browser方法,例子如下: browser=手机浏览器类型,如chrome 二.Open Application启 ...