基于AJAX的长轮询(long-polling)方式实现简单的聊天室程序
2016-02-21 12:28
751 查看
原理:
可以看:http://yiminghe.javaeye.com/blog/294781
AJAX 的出现使得 JavaScript 可以调用 XMLHttpRequest 对象发出 HTTP 请求,JavaScript 响应处理函数根据服务器返回的信息对 HTML 页面的显示进行更新。使用 AJAX 实现“服务器推”与传统的 AJAX 应用不同之处在于:
服务器端会阻塞请求直到有数据传递或超时才返回。
客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。
当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。
聊天页面的代码:
定义mm.js,定义发送消息,定义接收消息的JS函数
view plaincopy to clipboardprint?
Ext.onReady(function () {
getMsg();
});
function getMsg() {
Ext.Ajax.request({url:"getMsg", callback:function (options, success, response) {
if (success) {
Ext.DomHelper.append(Ext.get("main"), response.responseText, true);
}
getMsg();
}});
}
function putMsg() {
Ext.Ajax.request({url:"putMsg", params:{message:document.getElementByIdx_x_x("message").value}});
}
下面是获得message的servlet
view plaincopy to clipboardprint?
package hyjc.listener;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GetMsg extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
MessageList m = MessageList.getInstance();
boolean end = false;
while (!end) {
System.out.println("before get");
String msg = m.get();
System.out.println("after get " + msg);
out.write(msg + "
");
if (m.isEmpty()) {
end = true;
}
}
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
下面是添加消息的servlet
view plaincopy to clipboardprint?
package hyjc.listener;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class PutMsg extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
System.out.println("put message");
PrintWriter out = response.getWriter();
out.flush();
String msg = request.getParameter("message");
if (null != msg) {
MessageList.getInstance().add(msg);
} else {
System.out.println("添加消息:" + msg + "成果");
}
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
下面是存放消息的消息队列,内部用阻塞队列使用
view plaincopy to clipboardprint?
package hyjc.listener;
import java.util.Iterator;
import java.util.concurrent.LinkedBlockingQueue;
public class MessageList {
private static MessageList list = null;
private static Object key = new Object();
private MessageList() {
this.add("hello");
this.add("world");
}
public static MessageList getInstance() {
synchronized (key) {
if (list == null) {
list = new MessageList();
}
return list;
}
}
private LinkedBlockingQueue queue = new LinkedBlockingQueue();
public boolean isEmpty() {
return queue.isEmpty();
}
public int size() {
return queue.size();
}
public String get() {
try {
return queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
return null;
}
}
public void clear() {
queue.clear();
}
public void add(String msg) {
try {
queue.put(msg);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public Iterator iterator() {
return queue.iterator();
}
}
下面是演示效果,输入message,点击submit,就会添加到MessageList中,然后会在GetMsg中继续执行,实现长连接
可以看:http://yiminghe.javaeye.com/blog/294781
AJAX 的出现使得 JavaScript 可以调用 XMLHttpRequest 对象发出 HTTP 请求,JavaScript 响应处理函数根据服务器返回的信息对 HTML 页面的显示进行更新。使用 AJAX 实现“服务器推”与传统的 AJAX 应用不同之处在于:
服务器端会阻塞请求直到有数据传递或超时才返回。
客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。
当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。
聊天页面的代码:
定义mm.js,定义发送消息,定义接收消息的JS函数
view plaincopy to clipboardprint?
Ext.onReady(function () {
getMsg();
});
function getMsg() {
Ext.Ajax.request({url:"getMsg", callback:function (options, success, response) {
if (success) {
Ext.DomHelper.append(Ext.get("main"), response.responseText, true);
}
getMsg();
}});
}
function putMsg() {
Ext.Ajax.request({url:"putMsg", params:{message:document.getElementByIdx_x_x("message").value}});
}
下面是获得message的servlet
view plaincopy to clipboardprint?
package hyjc.listener;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class GetMsg extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
MessageList m = MessageList.getInstance();
boolean end = false;
while (!end) {
System.out.println("before get");
String msg = m.get();
System.out.println("after get " + msg);
out.write(msg + "
");
if (m.isEmpty()) {
end = true;
}
}
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
下面是添加消息的servlet
view plaincopy to clipboardprint?
package hyjc.listener;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class PutMsg extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
System.out.println("put message");
PrintWriter out = response.getWriter();
out.flush();
String msg = request.getParameter("message");
if (null != msg) {
MessageList.getInstance().add(msg);
} else {
System.out.println("添加消息:" + msg + "成果");
}
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
下面是存放消息的消息队列,内部用阻塞队列使用
view plaincopy to clipboardprint?
package hyjc.listener;
import java.util.Iterator;
import java.util.concurrent.LinkedBlockingQueue;
public class MessageList {
private static MessageList list = null;
private static Object key = new Object();
private MessageList() {
this.add("hello");
this.add("world");
}
public static MessageList getInstance() {
synchronized (key) {
if (list == null) {
list = new MessageList();
}
return list;
}
}
private LinkedBlockingQueue queue = new LinkedBlockingQueue();
public boolean isEmpty() {
return queue.isEmpty();
}
public int size() {
return queue.size();
}
public String get() {
try {
return queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
return null;
}
}
public void clear() {
queue.clear();
}
public void add(String msg) {
try {
queue.put(msg);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public Iterator iterator() {
return queue.iterator();
}
}
下面是演示效果,输入message,点击submit,就会添加到MessageList中,然后会在GetMsg中继续执行,实现长连接
相关文章推荐
- maven核心概念--生命周期
- 函数参数传递
- maven核心概念--生命周期
- 如何用AndroidStudio导入github项目
- 程序结构&&程序设计(三)
- Javascript自学-6
- reverse mapping checking getaddrinfo for bogon failed – POSSIBLE BREAK-IN ATTEMPT! 错误
- 骗骗骗!教会你创业的8大成功骗术
- 360将推出视频版的“今日头条”
- 一个工作快八年的老IT人士这几年沉浮总结的职场经验教训
- LaTeX学习记录
- Linux 基金会发布面向IoT设备的实时OS「Zephyr 项目」
- 【Linux 基础篇】之系统管理
- KMP算法
- android monkey
- JavaScript之面向对象浅析1
- 背景选择器
- java垃圾回收技术
- easyui报表导出
- 基于FBX SDK的FBX模型解析与加载 -(四)