【发布时间】:2012-04-15 17:38:30
【问题描述】:
附带条件:我不想将数据库用于以下用途。
我收到一个关闭的套接字异常,我将其归因于在 localhost 上运行的叶子节点的延迟。预计会有延迟,我只是不知道如何处理。
我知道,从一个单独的 CLI 程序中,叶子节点的响应正确并且实用程序类正在工作。对于这个应用程序,我可以从 glassfish 日志中看到:
nntp: <68 <x1-QQumhvcthNpaS3eWCQlR7Bleszk@gwene.org>
nntp: <69 <x1-N15vT7mtEkMzewjHjlTmjzBSpFY@gwene.org>
nntp: <70 <x1-cfsH29WrlKvYMd+t1ohsVSekIy0@gwene.org>
nntp: <71 <x1-DaQK7LTcaCQP3O3Us+8HTxTDALQ@gwene.org>
nntp: <72 <x1-1+PG1MuOkVUmzmY2XWRAWCKwbD8@gwene.org>
nntp: <73 <x1-sXoWsN3I56qalgUJAuT6+jWCYLE@gwene.org>
nntp: <74 <x1-osEXmt5CXnwu3eVGVAb4e11PZnY@gwene.org>
nntp: <.
nntp: >QUIT
nntp: <205 Always happy to serve!
INFO: GOT MESSAGES AS SO..
INFO: [gnu.mail.providers.nntp.NNTPMessage@1e2218b, gnu.mail.providers.nntp.NNTPMessage@10838ec, gnu.mail.providers.nntp.NNTPMessage@d14f1b, gnu.mail.providers.nntp.NNTPMessage@1a0b187, gnu.mail.providers.nntp.NNTPMessage@e74409, gnu.mail.providers.nntp.NNTPMessage@123ce36, gnu.mail.providers.nntp.NNTPMessage@1b7515a, gnu.mail.providers.nntp.NNTPMessage@3e0a57, gnu.mail.providers.nntp.NNTPMessage@118d5e0, gnu.mail.providers.nntp.NNTPMessage@1819b07, gnu.mail.providers.nntp.NNTPMessage@1e91886, gnu.mail.providers.nntp.NNTPMessage@493ab5, gnu.mail.providers.nntp.NNTPMessage@1ad7ec5, gnu.mail.providers.nntp.NNTPMessage@15dbf8d, gnu.mail.providers.nntp.NNTPMessage@1cae695, gnu.mail.providers.nntp.NNTPMessage@1e86f47, gnu.mail.providers.nntp.NNTPMessage@e1d295, gnu.mail.providers.nntp.NNTPMessage@1c87547, gnu.mail.providers.nntp.NNTPMessage@18b9691, gnu.mail.providers.nntp.NNTPMessage@14a0c6f, gnu.mail.providers.nntp.NNTPMessage@765340, gnu.mail.providers.nntp.NNTPMessage@53b2e4, gnu.mail.providers.nntp.NNTPMessage@10597ed, gnu.mail.providers.nntp.NNTPMessage@396c01, gnu.mail.providers.nntp.NNTPMessage@1e1f03d, gnu.mail.providers.nntp.NNTPMessage@63410a, gnu.mail.providers.nntp.NNTPMessage@433231, gnu.mail.providers.nntp.NNTPMessage@1945928, gnu.mail.providers.nntp.NNTPMessage@696ea0, gnu.mail.providers.nntp.NNTPMessage@1dde855, gnu.mail.providers.nntp.NNTPMessage@1c0559e, gnu.mail.providers.nntp.NNTPMessage@352a35, gnu.mail.providers.nntp.NNTPMessage@660b04, gnu.mail.providers.nntp.NNTPMessage@15d401f, gnu.mail.providers.nntp.NNTPMessage@11cddfb, gnu.mail.providers.nntp.NNTPMessage@31917d, gnu.mail.providers.nntp.NNTPMessage@46be43, gnu.mail.providers.nntp.NNTPMessage@7523ed, gnu.mail.providers.nntp.NNTPMessage@89a405, gnu.mail.providers.nntp.NNTPMessage@6f5b1b, gnu.mail.providers.nntp.NNTPMessage@c649d6, gnu.mail.providers.nntp.NNTPMessage@19882d, gnu.mail.providers.nntp.NNTPMessage@3b8201, gnu.mail.providers.nntp.NNTPMessage@d44937, gnu.mail.providers.nntp.NNTPMessage@112e45c, gnu.mail.providers.nntp.NNTPMessage@14e8cfc, gnu.mail.providers.nntp.NNTPMessage@a15e3, gnu.mail.providers.nntp.NNTPMessage@22f041, gnu.mail.providers.nntp.NNTPMessage@1cb71d7, gnu.mail.providers.nntp.NNTPMessage@19ee882, gnu.mail.providers.nntp.NNTPMessage@1b2d490, gnu.mail.providers.nntp.NNTPMessage@1a16b05, gnu.mail.providers.nntp.NNTPMessage@79412e, gnu.mail.providers.nntp.NNTPMessage@a66063, gnu.mail.providers.nntp.NNTPMessage@10203ea, gnu.mail.providers.nntp.NNTPMessage@14f0db5, gnu.mail.providers.nntp.NNTPMessage@10ceef3, gnu.mail.providers.nntp.NNTPMessage@1bc33e, gnu.mail.providers.nntp.NNTPMessage@af5b1a, gnu.mail.providers.nntp.NNTPMessage@860956, gnu.mail.providers.nntp.NNTPMessage@1cf1146, gnu.mail.providers.nntp.NNTPMessage@1770fb1, gnu.mail.providers.nntp.NNTPMessage@1a76bc3, gnu.mail.providers.nntp.NNTPMessage@940c94, gnu.mail.providers.nntp.NNTPMessage@1c5d10c, gnu.mail.providers.nntp.NNTPMessage@1fa00d, gnu.mail.providers.nntp.NNTPMessage@44ecf0, gnu.mail.providers.nntp.NNTPMessage@11f88e8, gnu.mail.providers.nntp.NNTPMessage@1554648, gnu.mail.providers.nntp.NNTPMessage@17921a7, gnu.mail.providers.nntp.NNTPMessage@1905dbf, gnu.mail.providers.nntp.NNTPMessage@fad175]
INFO: ..GOT MESSAGES AS SO
NNTP 消息最终会被加载。只是它似乎没有及时返回到 bean,或者,如果它确实返回,它可能是 bean 的错误实例。我推断第一个 bean 可以正常通过,但是另一个 bean 出现套接字问题,因为 Leafnode 很忙。看起来 bean 构造函数被多次调用,这当然没问题,但可能是第二个 bean 关闭套接字的原因。
那么,我如何隔离延迟问题,以便任何 MessageBean 都获得 err ?enum 单例? javax.mail.Message 的正确吗? (我使用的是 GNU NNTP 库,它比 Apache 好得多,而且运行良好。)
这是 facelets 客户端:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns:ui="http://java.sun.com/jsf/facelets"
template="./template.xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core">
<ui:define name="left">
<h:button id="submit" value="click me" />
</ui:define>
<ui:define name="content">
<ui:repeat value="#{messageBean.messages}" var="message">
<li>
<h:outputText value="#{message.messageNumber}" />
<h:outputText value="#{message.subject}" />
</li>
</ui:repeat>
</ui:define>
</ui:composition>
和支持 MessageBean 一样:
package net.bounceme.dur.nntp;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import javax.mail.Message;
@Named
@SessionScoped
public class MessageBean implements Serializable {
private static final long serialVersionUID = 1;
private static Logger logger = Logger.getLogger(MessageBean.class.getName());
private static Level level = Level.INFO;
public MessageBean() {
logger.log(level, "MessageBean..");
}
public List<Message> getMessages() throws Exception {
logger.log(level, "MessageBean.getMessages..");
List<Message> messages = new ArrayList<Message>();
messages = NNTP.getMessages();
logger.log(level, "GOT MESSAGES AS SO..");
logger.log(level, messages.toString());
logger.log(level, "..GOT MESSAGES AS SO");
return messages;
}
}
现在,MessageBean 调用实用程序 NNTP 类,该类与 localhost 上的叶节点交互,因此从 CLI 中它非常快。但是,对于 facelets,显然不够快,因为我不断收到套接字错误。
从记录到 Glassfish,我看到叶子节点正确地将文章返回到实用程序类,并且最终 MessageBean 甚至有一个大列表。
问题似乎是 MessageBean 可能有多个实例,应该有。然而,他们并不是都能够同时查询叶子节点,大概是成功的。也许这就是套接字错误的根源。
无论如何,我不想将 javax.mail.Message 持久化到数据库,leafnode 已经很好地持久化了消息。我非常想与本地主机上的叶子节点交互。
我需要某种可怕的枚举单例吗?这是我所知道的唯一“模式”,所以我认为它必须适用于这种情况。或者,是否有一些替代方法可以减慢 MessageBean 的速度,以确保它在将消息传递给 facelet 之前确实从实用程序 NNTP 类获取消息?或者,这样的延迟会导致某种错误吗?
这里有什么好的方法?我不是在尝试构建一个功能齐全的 NNTP 客户端,只是在摆弄leafnode,它有一些延迟。
-----------------------------------
解决方案:关闭套接字 properly 并使用容器类,如下面的 setEntities :
package net.bounceme.dur.nntp;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.mail.*;
public enum SingletonNNTP {
INSTANCE;
private final Logger logger = Logger.getLogger(SingletonNNTP.class.getName());
private final Level level = Level.INFO;
private Properties props = new Properties();
private List<Message> messages = new ArrayList<Message>();
private boolean loaded = false;
private List<MessageEntity> messageEntities = new ArrayList<MessageEntity>();
private SingletonNNTP() {
logger.logp(level, "SingletonNNTP", "SingletonNNTP", "only once...");
props = PropertiesReader.getProps();
if (!loaded) {
try {
loaded = setMessages();
} catch (Exception ex) {
Logger.getLogger(SingletonNNTP.class.getName()).log(Level.SEVERE, "FAILED TO LOAD MESSAGES", ex);
}
}
}
public List<Message> getMessages(boolean debug) throws Exception {
logger.logp(level, "SingletonNNTP", "getMessages", "returning messages");
return Collections.unmodifiableList(messages);
}
private boolean setMessages() throws Exception {
logger.logp(level, "SingletonNNTP", "setMessages", "connecting to leafnode");
Session session = Session.getDefaultInstance(props);
session.setDebug(false);
Store store = session.getStore(new URLName(props.getProperty("nntp.host")));
store.connect();
Folder root = store.getDefaultFolder();
Folder folder = root.getFolder(props.getProperty("nntp.group"));
folder.open(Folder.READ_ONLY);
Message[] msgs = folder.getMessages();
messages = Arrays.asList(msgs);
setEntities();
folder.close(false);
store.close();
return true;
}
public List<MessageEntity> getEntities() {
logger.logp(level, "SingletonNNTP", "getEntities", "getting entities");
for (MessageEntity m : messageEntities) {
for (Header h : m.getHeaders()) {
logger.log(level, h.toString());
}
}
return Collections.unmodifiableList(messageEntities);
}
private void setEntities() throws Exception {
logger.logp(level, "SingletonNNTP", "loadEntities", "trying to convert");
messageEntities = new ArrayList<MessageEntity>();
for (Message message : messages) {
MessageEntity entity = new MessageEntity();
Enumeration allHeaders = message.getAllHeaders();
List<Header> headers = new ArrayList<Header>();
while (allHeaders.hasMoreElements()) {
Header hdr = (Header) allHeaders.nextElement();
headers.add(hdr);
}
entity.setHeaders(headers);
entity.setSubject(message.getSubject());
entity.setContent(message.getContent().toString());
entity.setSentDate(message.getReceivedDate());
messageEntities.add(entity);
}
}
}
【问题讨论】:
标签: java sockets jsf glassfish facelets