001 /**
002 * GRANITE DATA SERVICES
003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S.
004 *
005 * This file is part of the Granite Data Services Platform.
006 *
007 * ***
008 *
009 * Community License: GPL 3.0
010 *
011 * This file is free software: you can redistribute it and/or modify
012 * it under the terms of the GNU General Public License as published
013 * by the Free Software Foundation, either version 3 of the License,
014 * or (at your option) any later version.
015 *
016 * This file is distributed in the hope that it will be useful, but
017 * WITHOUT ANY WARRANTY; without even the implied warranty of
018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
019 * GNU General Public License for more details.
020 *
021 * You should have received a copy of the GNU General Public License
022 * along with this program. If not, see <http://www.gnu.org/licenses/>.
023 *
024 * ***
025 *
026 * Available Commercial License: GraniteDS SLA 1.0
027 *
028 * This is the appropriate option if you are creating proprietary
029 * applications and you are not prepared to distribute and share the
030 * source code of your application under the GPL v3 license.
031 *
032 * Please visit http://www.granitedataservices.com/license for more
033 * details.
034 */
035 package org.granite.gravity.udp;
036
037 import java.io.IOException;
038 import java.io.ObjectOutput;
039 import java.util.HashMap;
040
041 import org.granite.context.AMFContextImpl;
042 import org.granite.context.GraniteContext;
043 import org.granite.context.SimpleGraniteContext;
044 import org.granite.gravity.AbstractChannel;
045 import org.granite.gravity.Gravity;
046 import org.granite.gravity.MessageReceivingException;
047 import org.granite.gravity.udp.UdpReceiver;
048 import org.granite.logging.Logger;
049
050 import flex.messaging.messages.AcknowledgeMessage;
051 import flex.messaging.messages.AsyncMessage;
052 import flex.messaging.messages.Message;
053
054 /**
055 * @author Franck WOLFF
056 */
057 public class UdpReceiverImpl implements UdpReceiver {
058
059 private static final Logger log = Logger.getLogger(UdpReceiverImpl.class);
060
061 public static final String GDS_CLIENT_UPD_PORT = "GDS_CLIENT_UDP_PORT";
062 public static final String GDS_SERVER_UDP_PORT = "GDS_SERVER_UDP_PORT";
063
064 private UdpChannel udpChannel;
065 private Message connect;
066
067 public UdpReceiverImpl(UdpChannel udpChannel, Message connect) {
068 if (udpChannel == null || connect == null)
069 throw new NullPointerException();
070
071 this.udpChannel = udpChannel;
072 this.connect = connect;
073 }
074
075 @Override
076 public AsyncMessage acknowledge(Message connectMessage) {
077 AcknowledgeMessage ack = new AcknowledgeMessage(connectMessage, true);
078 ack.setHeader(GDS_SERVER_UDP_PORT, Double.valueOf(udpChannel.getServerPort()));
079 return ack;
080 }
081
082 public void receive(AsyncMessage message) throws MessageReceivingException {
083 AbstractChannel gravityChannel = udpChannel.getGravityChannel();
084 Gravity gravity = gravityChannel.getGravity();
085
086 message.setCorrelationId(connect.getMessageId());
087 GraniteContext context = SimpleGraniteContext.createThreadInstance(
088 gravity.getGraniteConfig(),
089 gravity.getServicesConfig(),
090 new HashMap<String, Object>()
091 );
092 try {
093 ((AMFContextImpl)context.getAMFContext()).setCurrentAmf3Message(connect);
094
095 UdpOutputStream os = new UdpOutputStream();
096 ObjectOutput out = gravityChannel.newSerializer(context, os);
097 out.writeObject(new Message[] {message});
098
099 int sent = udpChannel.write(os.buffer(), 0, os.size());
100 if (sent != os.size())
101 log.debug("Partial data sent: %d of %d", sent, os.size());
102 }
103 catch (IOException e) {
104 throw new MessageReceivingException(message, e);
105 }
106 finally {
107 GraniteContext.release();
108 }
109 }
110
111 public boolean isClosed() {
112 return udpChannel == null;
113 }
114
115 public void close(boolean timeout) {
116 try {
117 udpChannel.close();
118 }
119 finally {
120 udpChannel = null;
121 connect = null;
122 }
123 }
124 }