从java向Flex客户端发送推送消息时发生NullPointerException

时间:2014-12-18 15:14:04

标签: java flex push-notification glassfish blazeds

我不是英语,如果我的英语非常糟糕,那就很抱歉......

为了解释我的问题,我在Eclipse for Java中嵌入了glassfish 3服务器,并通过BlazeDS与Flex客户端进行通信。

使用我的webservices没问题,但是我希望能够使用推送消息从我的服务器通知我的客户端,此时我遇到了问题。

我遵循了很多教程,这是我的工作:

public class TestServiceAdapter extends ServiceAdapter {

public TestServiceAdapter(){}


public Message createTestMessage(String message) {
    String objectToSend = new String(message);

    final AsyncMessage msg = new AsyncMessage();
    msg.setDestination("DataPush");
    msg.setClientId(UUIDUtils.createUUID());
    msg.setMessageId(UUIDUtils.createUUID());
    msg.setBody(objectToSend);
    return msg;
}

public void sendMessageToClients(Message msg) {
    ((MessageService) getDestination().getService()).pushMessageToClients(msg, false);
}

@Override
public Object invoke(Message message) {
    return null;
}

我编辑了flex xml:messaging-config.xml:

    <?xml version="1.0" encoding="UTF-8"?>
<service id="message-service" 
    class="flex.messaging.services.MessageService">

    <adapters>
        <adapter-definition id="actionscript" class="flex.messaging.services.messaging.adapters.ActionScriptAdapter" default="true" />
        <adapter-definition id="TestServiceAdapter" class="utils.TestServiceAdapter"/>
        <!-- <adapter-definition id="jms" class="flex.messaging.services.messaging.adapters.JMSAdapter"/> -->
    </adapters>

    <default-channels>
        <channel ref="my-amf"/>
    </default-channels>

    <destination id="TestServiceAdapterDestination">
        <channels>
            <channel ref="my-streaming-amf"/>
        </channels>
        <adapter ref="TestServiceAdapter"/>
    </destination>

</service>

这是我的services-config.xml重要代码:

<channels>
<channel-definition id="my-streaming-amf" class="mx.messaging.channels.StreamingAMFChannel">
    <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/streamingamf" class="flex.messaging.endpoints.StreamingAMFEndpoint"/>
    <properties>
         <!-- you don't need to set all these properties, this is just what we set, included for illustration, only -->
        <idle-timeout-minutes>0</idle-timeout-minutes>
        <max-streaming-clients>10</max-streaming-clients>
            <server-to-client-heartbeat-millis>5000</server-to-client-heartbeat-millis>
        <user-agent-settings>
            <user-agent match-on="Safari" kickstart-bytes="2048" max-streaming-connections-per-session="10"/>  
            <user-agent match-on="MSIE" kickstart-bytes="2048" max-streaming-connections-per-session="15"/> 
            <user-agent match-on="Firefox" kickstart-bytes="2048" max-streaming-connections-per-session="10"/>
        </user-agent-settings>
    </properties>

所以我的问题是当我部署我的服务器并使用该通知代码时,我得到一个nullPointerException:

((MessageService) getDestination().getService()).pushMessageToClients(msg, false);

目标永远不会从xml config初始化。

我不知道问题会发生什么。所以我请你帮忙!

2 个答案:

答案 0 :(得分:0)

您在java中使用的目的地(在您的情况下&#34; DataPush&#34;)需要与您在消息服务的服务配置中设置的频道相同,您已将其命名为&#34 ;我的-流式AMF&#34 ;. 将java中的目标更改为&#34; my-streaming-amf&#34;,或者将服务配置和消息传递配置中的通道重命名为&#34; DataPush&#34;,例如:

msg.setDestination("my-streaming-amf");

干杯

雅各。

答案 1 :(得分:0)

哦,我发现了我失败的地方。

我认为通过flex.messaging发送通知可以在没有活动线程的情况下完成,但事实并非如此。

如果您遇到同样的问题:

 package utils;

    import flex.messaging.MessageBroker;
    import flex.messaging.messages.AsyncMessage;
    import flex.messaging.messages.Message;
    import flex.messaging.services.MessageService;
    import flex.messaging.services.ServiceAdapter;
    import flex.messaging.util.UUIDUtils;

    public class Notifier extends ServiceAdapter {
        private static DataSender thread;

        public void start() {
            if(thread==null) {
                thread= new DataSender();
                thread.start();
            }
        }
        public void stop() {
        thread.running = false;
        thread = null; }


    public static class DataSender extends Thread{
        public boolean running=true;
        private static boolean refreshBool = false;

        public static void notifyClients(){
            refreshBool = true;
        }

        public void run() {
            MessageBroker msgBroker = MessageBroker.getMessageBroker(null);
            String clientID = UUIDUtils.createUUID();
            while (running) {
                if(refreshBool){
                    refreshBool = false;
                    AsyncMessage msg = new AsyncMessage();
                    msg.setDestination("DataPush");
                    msg.setClientId(clientID);
                    msg.setMessageId(UUIDUtils.createUUID());
                    msg.setBody("Refresh");
                    msgBroker.routeMessageToService(msg, null);
                }
                }

            }
        }

        public Object invoke(Message message) {

            AsyncMessage newMessage = (AsyncMessage) message;
            newMessage.setBody("Refresh");
            MessageService msgService = (MessageService) getDestination().getService();
            msgService.pushMessageToClients(newMessage, false); 
        return null;    
    }
}

messaging-config.xml和service-config.xml几乎相同。

我认为这不是一个优雅的解决方案,但是可行的,将来可以改进。