gpt4 book ai didi

javascript - cometd 消息发送两次

转载 作者:行者123 更新时间:2023-11-28 10:01:45 25 4
gpt4 key购买 nike

我想在我的项目中使用 Cometd,并在 Tomcat 7 服务器上尝试了 Jetty 8 版本。它有效,但消息被发送了两次。

为了检查它是否与项目的其余部分有关,我设置了一个仅具有此功能的独立项目,但我仍然收到两次消息。

我不知道为什么会这样。

项目中有5个文件:

  • pom.xml
  • web.xml
  • index.html
  • BayeuxInitializer.java
  • FormDataService.java

以下是每个文件的代码:

  • 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>

最佳答案

当您使用普通 channel (/sertal/formData) 时,所有发布的帖子都将发送到所有订阅的客户端,在您的情况下,即浏览器本身和 Bayeux 服务。因此,您将收到两个答案:一个是您发布的帖子,另一个是您的服务的响应。

解决方案:您不想发布您的formData,您希望它交付:

      ...
t.onTick = function() {
dojox.cometd.deliver( '/sertal/formData', { count: i++ } );
};
...

还有其他解决方案,例如使用服务 channel 而不是普通 channel 。看这个CometD FAQ Entry以获得进一步的解释。

更新:

我保留了在我的机器上进行这项工作所需的另一项更改:需要在 addOnLoad 处理程序之外调用 dojo.require

     ...   
dojo.require("dojox.cometd");
dojo.require("dojox.timing");

dojo.addOnLoad(function () {
...

我一直在使用dojo v1.7.1。

关于javascript - cometd 消息发送两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9052510/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com