您的位置:首页 > 其它

基于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中继续执行,实现长连接

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: