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] + "
";
writer.println(forecast);
log("Writing:" + forecast);
}
writer.flush();
writer.close();
connection = null;
log("Closing connection");
} catch (IOException e) {
log("IOExeption sending message", e);
}
}
}
}
这个类基本上是样板代码,与Comet 没有直接的关系。但是,有两点要注意。这个类含有一个ServletResponse 对象。回头看看清单2 中的event 方法,当事件为BEGIN 时,response 对象被传入到MessageSender 中。在MessageSender 的run 方法中,它使用ServletResponse 将数据发送回客户机。注意,一旦发送完所有排队等待的消息后,它将关闭连接。这样就实现了长轮询。如果要实现流风格的Comet,那么需要使连接保持开启,但是仍然刷新数据。
回头看清单2 可以发现,其中创建了一个Weatherman 类。正是这个类使用MessageSender 将数据发送回客户机。这个类使用Yahoo RSS feed 获得不同地区的天气信息,并将该信息发送到客户机。这是一个特别设计的例子,用于模拟以异步方式发送数据的数据源。清单4 显示了它的代码。
清单4. Weatherman
private class Weatherman implements Runnable{
private final List
private final String YAHOO_WEATHER = "http://weather.yahooapis.com/forecastrss p=";
public Weatherman(Integer... zips) {
zipCodes = new ArrayList
for (Integer zip : zips) {
try {
zipCodes.add(new URL(YAHOO_WEATHER + zip));
} catch (Exception e) {
// dont add it if it sucks
}
}
}
public void run() {
int i = 0;
while (i >= 0) {
int j = i % zipCodes.size();
SyndFeedInput input = new SyndFeedInput();
try {
SyndFeed feed = input.build(new InputStreamReader(zipCodes.get(j)
.openStream()));
SyndEntry entry = (SyndEntry) feed.getEntries().get(0);
messageSender.send(entryToHtml(entry));
Thread.sleep(30000L);
} catch (Exception e) {
// just eat it, eat it
}
i++;
}
}
private String entryToHtml(SyndEntry entry){
StringBuilder html = new StringBuilder("
");
html.append(entry.getTitle());
html.append("");
html.append(entry.getDescription().getValue());
return html.toString();
}
}
这个类使用Project Rome 库解析来自Yahoo Weather 的RSS fee