throw org.atmosphere.cpr.AtmosphereResourceImpl:suspend()操作期间的异常java.lang.NullPointerException

时间:2015-09-07 05:39:32

标签: dropwizard atmosphere

我是的新手 - websocket。我正在进行私人聊天。我正在使用框架。

以下是我的代码:

service.java

@Override
public void run(ServiceConfiguration config, Environment environment)throws Exception {         
    AtmosphereServlet servlet = new AtmosphereServlet();
    servlet.framework().addInitParameter("com.sun.jersey.config.property.packages", "dk.cooldev.chatroom.resources.websocket");
    servlet.framework().addInitParameter(ApplicationConfig.WEBSOCKET_CONTENT_TYPE, "application/json");
    servlet.framework().addInitParameter(ApplicationConfig.WEBSOCKET_SUPPORT, "true");
    ServletRegistration.Dynamic servletHolder = environment.servlets().addServlet("Chat", servlet);
    servletHolder.addMapping("/chat/*");``
}

ChatRoom.java

package resource;    
import org.atmosphere.config.service.DeliverTo;
import org.atmosphere.config.service.Disconnect;
import org.atmosphere.config.service.ManagedService;
import org.atmosphere.config.service.Message;
import org.atmosphere.config.service.PathParam;
import org.atmosphere.config.service.Ready;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.AtmosphereResourceEvent;
import org.atmosphere.cpr.AtmosphereResourceFactory;
import org.atmosphere.cpr.Broadcaster;
import org.atmosphere.cpr.BroadcasterFactory;
import org.atmosphere.cpr.MetaBroadcaster;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import representation.UserMessage;
import utility.ChatProtocol;
import utility.JacksonEncoder;
import utility.ProtocolDecoder;
import utility.UserDecoder;

import javax.inject.Inject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;

@ManagedService(path = "/chat/{room: [a-zA-Z][a-zA-Z_0-9]*}")
public class ChatRoom {
    private final Logger logger = LoggerFactory.getLogger(ChatRoom.class);

    private final ConcurrentHashMap<String, String> users = new ConcurrentHashMap<String, String>();

    private final static String CHAT = "/chat/";

    @PathParam("room")
    private String chatroomName;

    @Inject
    private BroadcasterFactory factory;

    @Inject
    private AtmosphereResourceFactory resourceFactory;

    @Inject
    private MetaBroadcaster metaBroadcaster;

    /**
     * Invoked when the connection as been fully established and suspended, e.g ready for receiving messages.
     *
     * @param r
     */
    @Ready(encoders = {JacksonEncoder.class})
    @DeliverTo(DeliverTo.DELIVER_TO.ALL)
    public ChatProtocol onReady(final AtmosphereResource r) {
        r.suspend();
        logger.info("Browser {} connected.", r.uuid());
        return new ChatProtocol(users.keySet(), getRooms(factory.lookupAll()));
    }

    private static Collection<String> getRooms(Collection<Broadcaster> broadcasters) {
        Collection<String> result = new ArrayList<String>();
        for (Broadcaster broadcaster : broadcasters) {
            if (!("/*".equals(broadcaster.getID()))) {
                // if no room is specified, use ''
                String[] p = broadcaster.getID().split("/");
                result.add(p.length > 2 ? p[2] : "");
            }
        };
        return result;
    }

    /**
     * Invoked when the client disconnect or when an unexpected closing of the underlying connection happens.
     *
     * @param event
     */
    @Disconnect
    public void onDisconnect(AtmosphereResourceEvent event) {
        if (event.isCancelled()) {
            // We didn't get notified, so we remove the user.
            users.values().remove(event.getResource().uuid());
            logger.info("Browser {} unexpectedly disconnected", event.getResource().uuid());
        } else if (event.isClosedByClient()) {
            logger.info("Browser {} closed the connection", event.getResource().uuid());
        }
    }

    /**
     * Simple annotated class that demonstrate how {@link org.atmosphere.config.managed.Encoder} and {@link org.atmosphere.config.managed.Decoder
     * can be used.
     *
     * @param message an instance of {@link ChatProtocol }
     * @return
     * @throws IOException
     */
    @Message(encoders = {JacksonEncoder.class}, decoders = {ProtocolDecoder.class})
    public ChatProtocol onMessage(ChatProtocol message) throws IOException {

        if (!users.containsKey(message.getAuthor())) {
            users.put(message.getAuthor(), message.getUuid());
            return new ChatProtocol(message.getAuthor(), " entered room " + chatroomName, users.keySet(), getRooms(factory.lookupAll()));
        }

        if (message.getMessage().contains("disconnecting")) {
            users.remove(message.getAuthor());
            return new ChatProtocol(message.getAuthor(), " disconnected from room " + chatroomName, users.keySet(), getRooms(factory.lookupAll()));
        }

        message.setUsers(users.keySet());
        logger.info("{} just send {}", message.getAuthor(), message.getMessage());
        return new ChatProtocol(message.getAuthor(), message.getMessage(), users.keySet(), getRooms(factory.lookupAll()));
    }

    @Message(decoders = {UserDecoder.class})
    public void onPrivateMessage(UserMessage user) throws IOException {
        String userUUID = users.get(user.getUser());
        if (userUUID != null) {
            // Retrieve the original AtmosphereResource
            AtmosphereResource r = resourceFactory.find(userUUID);

            if (r != null) {
                ChatProtocol m = new ChatProtocol(user.getUser(), " sent you a private message: " + user.getMessage().split(":")[1], users.keySet(), getRooms(factory.lookupAll()));
                if (!user.getUser().equalsIgnoreCase("all")) {
                    factory.lookup(CHAT + chatroomName).broadcast(m, r);
                }
            }
        } else {
            ChatProtocol m = new ChatProtocol(user.getUser(), " sent a message to all chatroom: " + user.getMessage().split(":")[1], users.keySet(), getRooms(factory.lookupAll()));
            metaBroadcaster.broadcastTo("/*", m);
        }
    }

}

现在,当我运行我的应用程序时,它正在抛出

  

resource.ChatRoom:浏览器72196f81-3425-4137-8f37-c5aa6b134534已连接。   警告:org.atmosphere.cpr.AtmosphereResourceImpl:suspend()操作期间的异常java.lang.NullPointerException

请帮我解决此异常。

2 个答案:

答案 0 :(得分:1)

如果收到该警告,则应从广播侦听器列表中删除您的套接字。传递给广播公司的消息,该消息调用OutingBroadcast(Object message)为null,并且不处理null情况。在drop-wizard中,该消息对于onReady方法变为null。快速解决方案是扩展广播者并覆盖该方法并处理null情况。

我希望它会有所帮助。我在使用RedisBroadcaster时遇到了同样的问题,并且通过处理null情况进行了修复。

public void outgoingBroadcast(Object message) {
    // Marshal the message outside of the sync block.
    if(message == null){
        return;
    }
    String contents = message.toString();

答案 1 :(得分:0)

我只是设置我自己的聊天样本并遇到同样的问题。就我而言,注入的字段不可用。

在你的情况下,我会说它是

之一
@Inject
private BroadcasterFactory factory;

@Inject
private AtmosphereResourceFactory resourceFactory;

@Inject
private MetaBroadcaster metaBroadcaster;

没有正确接线。我之前没有使用过drop-wizard所以我无法建议如何确保正确配置它们。

这种类型的问题很容易看到我为跟踪记录配置气氛。例如对于logback添加以下行

<logger name="org.atmosphere" level="TRACE" /> 

由于

赖安