1.public class ChatServlet
2. extends HttpServlet implements CometProcessor {
3.
4. protected ArrayList<HttpServletResponse> connections =
5. new ArrayList<HttpServletResponse>();
6. protected MessageSender messageSender = null;
7.
8. public void init() throws ServletException {
9. messageSender = new MessageSender();
10. Thread messageSenderThread =
11. new Thread(messageSender, "MessageSender[" + getServletContext().getContextPath() + "]");
12. messageSenderThread.setDaemon(true);
13. messageSenderThread.start();
14. }
15.
16. public void destroy() {
17. connections.clear();
18. messageSender.stop();
19. messageSender = null;
20. }
21.
22. /**
23. * Process the given Comet event.
24. *
25. * @param event The Comet event that will be processed
26. * @throws IOException
27. * @throws ServletException
28. */
29. public void event(CometEvent event)
30. throws IOException, ServletException {
31. HttpServletRequest request = event.getHttpServletRequest();
32. HttpServletResponse response = event.getHttpServletResponse();
33. if (event.getEventType() == CometEvent.EventType.BEGIN) {
34. log("Begin for session: " + request.getSession(true).getId());
35. PrintWriter writer = response.getWriter();
36. writer.println("<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\">");
37. writer.println("<head><title>JSP Chat</title></head><body bgcolor=\"#FFFFFF\">");
38. writer.flush();
39. synchronized(connections) {
40. connections.add(response);
41. }
42. } else if (event.getEventType() == CometEvent.EventType.ERROR) {
43. log("Error for session: " + request.getSession(true).getId());
44. synchronized(connections) {
45. connections.remove(response);
46. }
47. event.close();
48. } else if (event.getEventType() == CometEvent.EventType.END) {
49. log("End for session: " + request.getSession(true).getId());
50. synchronized(connections) {
51. connections.remove(response);
52. }
53. PrintWriter writer = response.getWriter();
54. writer.println("</body></html>");
55. event.close();
56. } else if (event.getEventType() == CometEvent.EventType.READ) {
57. InputStream is = request.getInputStream();
58. byte[] buf = new byte[512];
59. do {
60. int n = is.read(buf); //can throw an IOException
61. if (n > 0) {
62. log("Read " + n + " bytes: " + new String(buf, 0, n)
63. + " for session: " + request.getSession(true).getId());
64. } else if (n < 0) {
65. error(event, request, response);
66. return;
67. }
68. } while (is.available() > 0);
69. }
70. }
71.
72. public class MessageSender implements Runnable {
73.
74. protected boolean running = true;
75. protected ArrayList<String> messages = new ArrayList<String>();
76.
77. public MessageSender() {
78. }
79.
80. public void stop() {
81. running = false;
82. }
83.
84. /**
85. * Add message for sending.
86. */
87. public void send(String user, String message) {
88. synchronized (messages) {
89. messages.add("[" + user + "]: " + message);
90. messages.notify();
91. }
92. }
93.
94. public void run() {
95.
96. while (running) {
97.
98. if (messages.size() == 0) {
99. try {
100. synchronized (messages) {
101. messages.wait();
102. }
103. } catch (InterruptedException e) {
104. // Ignore
105. }
106. }
107.
108. synchronized (connections) {
109. String[] pendingMessages = null;
110. synchronized (messages) {
111. pendingMessages = messages.toArray(new String[0]);
112. messages.clear();
113. }
114. // Send any pending message on all the open connections
115. for (int i = 0; i < connections.size(); i++) {
116. try {
117. PrintWriter writer = connections.get(i).getWriter();
118. for (int j = 0; j < pendingMessages.length; j++) {
119. writer.println(pendingMessages[j] + "<br>");
120. }
121. writer.flush();
122. } catch (IOException e) {
123. log("IOExeption sending message", e);
124. }
125. }
126. }
127.
128. }
129.
130. }
131.
132. }
133.
134.}
135.
时间: 2024-10-28 13:57:46