comet 推送 消息 聊天

本文详细介绍了如何在 Tomcat 中实现 Comet 推送功能,包括引入必要的 jar 包、修改 server.xml 文件、配置 servlet 和 web.xml 以及实现前端页面与服务器之间的长连接。通过提供完整的代码示例,帮助开发者轻松实现实时推送消息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

需要的jar包以及基础的配置参考:

tomcat comet 推送 技术 入门 

直接切入正题:

 

首先引入tomcat的lib目录下的jar包:

 

catalina.jar,servlet-api.jar

 

另外要修改tomcat的server.xml,将protocal="http/1.1"什么的修改为:

 

<Connector port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" 
               connectionTimeout="20000" 
               redirectPort="8443" />

 

 

这样就让tomcat支持推送功能了

 

首先是servlet(带有注释):

 

package nio.comet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.catalina.CometEvent;
import org.apache.catalina.CometProcessor;

public class ChatCometServlet extends HttpServlet implements CometProcessor{
	private static final long serialVersionUID = 1L;
	private List<CometEvent> events = new ArrayList<CometEvent>();

	@Override
	public void event(CometEvent event) throws IOException, ServletException {
		HttpServletRequest request = event.getHttpServletRequest();
		String path = request.getRequestURI();
		if(path.indexOf("setComet") != -1){
			//发送消息的请求
			String message = request.getParameter("message");
			//遍历所有的CometEvent,将消息发送出去
			synchronized(events){
				//使用list的遍历器
				Iterator<CometEvent> iterator = events.iterator(); 
				CometEvent e = null;
				while(iterator.hasNext()){
					e = iterator.next();
					HttpServletResponse res = e.getHttpServletResponse();
					//设置响应的编码和类型
					res.setCharacterEncoding("utf-8");
					res.setContentType("text/plain");
					PrintWriter writer = res.getWriter();
					writer.write(message);
					writer.flush();
					//一定要调用list保存的CometEvent对象的close方法关闭,这样才可以及时将消息推送出去
					e.close();
					//删除的时候要使用iterator的删除方法,否则可能会引发cuncurrentModifyException
					iterator.remove();
				}
			}
			//最后关闭当前请求的CometEvent
			event.close();
			return;
		}else if(path.indexOf("getComet") != -1){
			//获取消息的请求
			if(event.getEventType() == CometEvent.EventType.BEGIN){
				//begin阶段,设置超时时间,并将CometEvent对于保存到list中,其他阶段均返回ERROR(简单处理)
				event.setTimeout(20000);
				synchronized(events){
					events.add(event);
				}
				return;
			}else if(event.getEventType() == CometEvent.EventType.END){
				synchronized(events){
					HttpServletResponse res = event.getHttpServletResponse();
					res.setCharacterEncoding("utf-8");
					res.setContentType("text/plain");
					PrintWriter writer = res.getWriter();
					writer.write("ERROR");
					writer.flush();
					event.close();
					events.remove(event);
				}
				return;
			}else if(event.getEventType() == CometEvent.EventType.ERROR){
				synchronized(events){
					HttpServletResponse res = event.getHttpServletResponse();
					res.setCharacterEncoding("utf-8");
					res.setContentType("text/plain");
					PrintWriter writer = res.getWriter();
					writer.write("ERROR");
					writer.flush();
					event.close();
					events.remove(event);
				}
				return;
			}else if(event.getEventType() == CometEvent.EventType.READ){
				synchronized(events){
					HttpServletResponse res = event.getHttpServletResponse();
					res.setCharacterEncoding("utf-8");
					res.setContentType("text/plain");
					PrintWriter writer = res.getWriter();
					writer.write("ERROR");
					writer.flush();
					event.close();
					events.remove(event);
				}
				return;
			}
		}
	}
}

 

 

然后再web.xml中配置servlet:

 

	<servlet>
		<servlet-name>mycomet</servlet-name>
		<servlet-class>nio.comet.ChatCometServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>mycomet</servlet-name>
		<url-pattern>/comet/*</url-pattern>
	</servlet-mapping>

 

然后就是页面了(里面需要引入jquery):

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>My JSP 'chat.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<script type="text/javascript" src="upload/js/jquery.min.js"></script>
	<script type="text/javascript">
		$(function(){
			//页面加载完之后就发起读取消息的长连接
			read();
		});
		//发送消息
		function send(){
			var f = document.forms['cometForm'];
			$.post("comet/setComet",$(f).serialize());
		}
		//读取消息
		function read(){
			$.ajax({
			   type: "POST",
			   url: "comet/getComet",
			   success: function(data){
			     if("ERROR" != data){
			    	 $("#show").html($("#show").html()+'<br/>'+data);
			     }
				 read();
			   }
			});
		}
	</script>
  </head>
  <body>
    <form name="cometForm">
	     <input type="text" name="message"/>
	     <input type="button" value="send" onclick="send();"/>
    </form>
      消息:
    <div id="show"></div>
  </body>
</html>

 

然后就可以打开多个浏览器测试了。。。

 

 

内容概要:本文详细探讨了基于MATLAB/SIMULINK的多载波无线通信系统仿真及性能分析,重点研究了以OFDM为代表的多载波技术。文章首先介绍了OFDM的基本原理和系统组成,随后通过仿真平台分析了不同调制方式的抗干扰性能、信道估计算法对系统性能的影响以及同步技术的实现与分析。文中提供了详细的MATLAB代码实现,涵盖OFDM系统的基本仿真、信道估计算法比较、同步算法实现和不同调制方式的性能比较。此外,还讨论了信道特征、OFDM关键技术、信道估计、同步技术和系统级仿真架构,并提出了未来的改进方向,如深度学习增强、混合波形设计和硬件加速方案。; 适合人群:具备无线通信基础知识,尤其是对OFDM技术有一定了解的研究人员和技术人员;从事无线通信系统设计与开发的工程师;高校通信工程专业的高年级本科生和研究生。; 使用场景及目标:①理解OFDM系统的工作原理及其在多径信道环境下的性能表现;②掌握MATLAB/SIMULINK在无线通信系统仿真中的应用;③评估不同调制方式、信道估计算法和同步算法的优劣;④为实际OFDM系统的设计和优化提供理论依据和技术支持。; 其他说明:本文不仅提供了详细的理论分析,还附带了大量的MATLAB代码示例,便于读者动手实践。建议读者在学习过程中结合代码进行调试和实验,以加深对OFDM技术的理解。此外,文中还涉及了一些最新的研究方向和技术趋势,如AI增强和毫米波通信,为读者提供了更广阔的视野。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值