+1 امتیاز
قبل در برنامه نویسی توسط (7.2هزار امتیاز)

با مراجعه به یکی از لینکهای موجود در جواب مرتبط اقدام به تهیه یک سرولت برای ایجاد کامت کردم.

برای این منظور فایل server.xml در tomcat را به شیوه زیر تغییر دادم:

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

و یک سرولت به صورت زیر ایجاد کردم:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mohi.comet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import javax.servlet.ServletException;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.comet.CometEvent;
import org.apache.catalina.comet.CometProcessor;

/**
 *
 * @author mohsen
 */
@WebServlet("/mn")
public class NotificationComet extends HttpServlet implements CometProcessor {
    public static int ii = 1;

    private MessageSender messageSender = null;
    private static final Integer TIMEOUT = 60 * 1000;

    @Override
    public void destroy() {
//        messageSender.stop();
        messageSender = null;

    }

    @Override
    public void init() throws ServletException {
        messageSender = new MessageSender();
        Thread messageSenderThread =
                new Thread(messageSender, "MessageSender[" + getServletContext()
                .getContextPath() + "]");
        messageSenderThread.setDaemon(true);
        messageSenderThread.start();

    }

    @Override
    public void event(final CometEvent event) throws IOException, ServletException {
        HttpServletRequest request = event.getHttpServletRequest();
        HttpServletResponse response = event.getHttpServletResponse();
        if (event.getEventType() == CometEvent.EventType.BEGIN) {
            request.setAttribute("org.apache.tomcat.comet.timeout", TIMEOUT);
            log("Begin for session: " + request.getSession(true).getId());
            messageSender.setConnection(response);
            Weatherman weatherman = new Weatherman();
            new Thread(weatherman).start();
        } else if (event.getEventType() == CometEvent.EventType.ERROR) {
            log("Error for session: " + request.getSession(true).getId());
            event.close();
        } else if (event.getEventType() == CometEvent.EventType.END) {
            log("End for session: " + request.getSession(true).getId());
            event.close();
        } else if (event.getEventType() == CometEvent.EventType.READ) {
            throw new UnsupportedOperationException(
                    "This servlet does not accept data");
        }

    }

private class MessageSender implements Runnable {

    protected boolean running = true;
    protected final ArrayList<String> messages = new ArrayList<String>();
    private ServletResponse connection;

    private synchronized void setConnection(ServletResponse connection) {
        this.connection = connection;
        notify();
    }

    public void send(String message) {
        synchronized (messages) {
            messages.add(message);
            System.err.println("Message added #messages=" + messages.size());
            messages.notify();
        }
    }

    public void run() {
        while (running) {
            if (messages.size() == 0) {
                try {
                    synchronized (messages) {
                        messages.wait();
                    }
                } catch (InterruptedException e) {
                    // Ignore
                }
            }
            String[] pendingMessages = null;
            synchronized (messages) {
                pendingMessages = messages.toArray(new String[0]);
                messages.clear();
            }
            try {
                if (connection == null) {
                    try {
                        synchronized (this) {
                            wait();
                        }
                    } catch (InterruptedException e) {
                        // Ignore
                    }
                }
                PrintWriter writer = connection.getWriter();
                for (int j = 0; j < pendingMessages.length; j++) {
                    final String forecast = pendingMessages[j] + "<br>";
                    writer.println(forecast);
                    System.err.println("Writing:" + forecast);
                }
                writer.flush();
                writer.close();
                connection = null;
                System.err.println("Closing connection");
            } catch (IOException e) {
                System.err.println("IOExeption sending message");
                e.printStackTrace();
            }
        }
    }
}

    private class Weatherman implements Runnable {

        public void run() {
            int i = 0;
            while (i >= 0) {
                try {
                    messageSender.send(i+"gooooolaaaaa"+ii++);
                    Thread.sleep(30000L);
                } catch (Exception e) {
                    // just eat it, eat it
                }
                i++;
            }
        }

    }
}

و در نهایت یک jsp هم به صورت زیر:


<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Comet Weather</title>
        <SCRIPT TYPE="text/javascript">
            function go() {
                var url = "http://localhost:8080/test_servlet/mn"
                var request = new XMLHttpRequest();
                request.open("GET", url, true);
                request.setRequestHeader("Content-Type", "application/x-javascript;");
                request.onreadystatechange = function() {
                    if (request.readyState == 4) {
                        if (request.status == 200) {
                            if (request.responseText) {
                                document.getElementById("forecasts").innerHTML =
                                        request.responseText;
                            }
                        }
                        go();
                    }
                };
                request.send(null);
            }
        </SCRIPT>
    </head>
    <body>
        <h1>Rapid Fire Weather </h1>
        <input type="button" onclick="go()" value="برو!"></input>
        <div id="forecasts"></div>
    </body>
</html>

اما مشکلم در اینجا است که پس از فشردن دکمه برو! متد event موجود servlet به صورت پشت سر هم و بدون وقفه فراخوانی می شود و بدون وقفه Thread های جدید ایجاد می شود. مشکل کارم از کجاست؟ 

قبل توسط (7.2هزار امتیاز)
پ . ن: با حذف کردن متد بازگشتی go ازدرون کد جاوا اسکریپت. باید برای هر بار به روز رسانی دکمه برو! را فشار دهم.

سوالات مشابه

+2 امتیاز
1 پاسخ 388 بازدید
سوال شده 10 سال قبل در برنامه نویسی توسط kashi (7.2هزار امتیاز)
+1 امتیاز
1 پاسخ 704 بازدید
سوال شده 10 سال قبل در برنامه نویسی توسط kashi (7.2هزار امتیاز)
+1 امتیاز
2 پاسخ 2.6هزار بازدید
+2 امتیاز
2 پاسخ 639 بازدید
سوال شده 4 سال قبل در برنامه نویسی توسط 1993 (242 امتیاز)
0 امتیاز
1 پاسخ 418 بازدید
0 امتیاز
2 پاسخ 363 بازدید
سوال شده 10 سال قبل در برنامه نویسی توسط Saeed Zarinfam (1.1هزار امتیاز)
+2 امتیاز
1 پاسخ 881 بازدید
0 امتیاز
1 پاسخ 331 بازدید
...