我想在我的项目中使用Cometd并在Tomcat 7服务器上尝试Jetty 8版本。它可以工作,但邮件正在发送两次。
为了检查它是否与项目的其余部分有关,我设置了一个只有这个功能的独立项目,我仍然收到两次消息。
我无法找出原因。
项目中有5个文件:
以下是每个文件的代码:
的web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>Sertal Vision</display-name>
<servlet>
<servlet-name>cometd</servlet-name>
<servlet-class>org.cometd.server.CometdServlet</servlet-class>
<init-param>
<param-name>timeout</param-name>
<param-value>60000</param-value>
</init-param>
<init-param>
<param-name>logLevel</param-name>
<param-value>3</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>bayeux-init</servlet-name>
<servlet-class>ch.sertal.server.BayeuxInitializer</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cometd</servlet-name>
<url-pattern>/cometd/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>bayeux-init</servlet-name>
<url-pattern>/bayeux/servlet/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>continuation</filter-name>
<filter-class>org.eclipse.jetty.continuation.ContinuationFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>continuation</filter-name>
<url-pattern>/cometd/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
的index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<script type="text/javascript" src="js/dojo/dojo/dojo.js"></script>
<script type="text/javascript">
var subscription = undefined;
dojo.addOnLoad( function () {
dojo.require( "dojox.cometd" );
dojo.require("dojox.timing");
// Disconnect when the page unloads
dojo.addOnUnload( function () {
dojox.cometd.disconnect( true );
} );
var cometURL = "cometd";
dojox.cometd.init( cometURL );
var subscription = dojox.cometd.subscribe( "/sertal/formData", function ( message ) {
dojo.create( "li", {
innerHTML:message.data.count
}, dojo.byId( "message-list" ) );
} );
i = 1;
var t = new dojox.timing.Timer();
t.setInterval( 1000 );
t.onTick = function() {
dojox.cometd.publish( '/sertal/formData', { count: i++ } );
};
t.start();
} );
</script>
</head>
<body>
<div>
<ul id="message-list"/>
</div>
</body>
</html>
BayeuxInitializer.java
package ch.sertal.server;
import org.cometd.bayeux.server.BayeuxServer;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
public class BayeuxInitializer extends GenericServlet {
private static final long serialVersionUID = -9089442901563633963L;
@Override
public void init() throws ServletException {
BayeuxServer bayeux = ( BayeuxServer ) getServletContext().getAttribute( BayeuxServer.ATTRIBUTE );
// new HelloService( bayeux );
new FormDataService( bayeux, getServletContext() );
}
@Override
public void service( ServletRequest servletRequest, ServletResponse servletResponse ) throws ServletException, IOException {
throw new ServletException( "sorry :-)" );
}
}
FormDataService.java
package ch.sertal.server;
import org.cometd.bayeux.Message;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.bayeux.server.ServerSession;
import org.cometd.server.AbstractService;
import javax.servlet.ServletContext;
import java.util.Map;
/**
* Created by IntelliJ IDEA.
* User: micha.roon
* Date: 1/16/12
* Time: 12:25 PM
* To change this template use File | Settings | File Templates.
*/
public class FormDataService extends AbstractService {
private ServletContext context = null;
public FormDataService( BayeuxServer bayeux, ServletContext context ) {
super( bayeux, "hello" );
this.context = context;
addService( "/sertal/formData", "processFormData" );
System.out.println( "New FormDataService" );
}
public void processFormData( final ServerSession remote, Message message ) {
Map<String, Object> input = message.getDataAsMap();
remote.deliver( getServerSession(), "/sertal/formData", input, null );
}
}
的pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>BayeuxTest</groupId>
<artifactId>BayeuxTest</artifactId>
<version>1.0</version>
<build>
<plugins>
<!--compiler plugin-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>tomcat-maven-plugin</artifactId>
<version>1.1</version>
<configuration>
<username>${tomcat.username}</username>
<password>${tomcat.password}</password>
<url>${tomcat.manager}</url>
<path>${tomcat.context}</path>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<!--for cometd support-->
<dependency>
<groupId>org.cometd.java</groupId>
<artifactId>bayeux-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.cometd.javascript</groupId>
<artifactId>cometd-javascript-jquery</artifactId>
<version>2.3.1</version>
<type>war</type>
</dependency>
<dependency>
<groupId>org.cometd.java</groupId>
<artifactId>cometd-java-server</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
<version>8.0.4.v20111024</version>
<exclusions>
<exclusion>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
</project>
答案 0 :(得分:0)
当您使用普通频道( / sertal / formData )时,所有发布的帖子都将发送给所有订阅的客户端,在您的情况下是浏览器本身和Bayeux服务。因此,您将收到两个答案:一个是您发布的帖子,另一个是您服务的回复。
解决方案:您不希望publish
使用formData,您希望deliver
编辑:
...
t.onTick = function() {
dojox.cometd.deliver( '/sertal/formData', { count: i++ } );
};
...
还有其他解决方案,例如使用服务频道而不是普通频道。有关详细说明,请参阅此CometD FAQ Entry。
更新:
我保留了另一项必要的更改,以便在我的计算机上执行此操作:dojo.require
需要在addOnLoad
处理程序之外调用。
...
dojo.require("dojox.cometd");
dojo.require("dojox.timing");
dojo.addOnLoad(function () {
...
我一直在使用dojo v1.7.1。