001/* 002 * GWTEventService 003 * Copyright (c) 2011 and beyond, strawbill UG (haftungsbeschr?nkt) 004 * 005 * This is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU Lesser General Public License as 007 * published by the Free Software Foundation; either version 3 of 008 * the License, or (at your option) any later version. 009 * Other licensing for GWTEventService may also be possible on request. 010 * Please view the license.txt of the project for more information. 011 * 012 * This software is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this software; if not, write to the Free 019 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 020 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 021 */ 022package de.novanic.eventservice.client.connection.strategy.connector.streaming; 023 024import com.google.gwt.core.client.GWT; 025import com.google.gwt.user.client.rpc.SerializationException; 026import com.google.gwt.user.client.rpc.SerializationStreamFactory; 027import com.google.gwt.user.client.rpc.SerializationStreamReader; 028import com.google.gwt.user.client.rpc.ServiceDefTarget; 029import com.google.gwt.user.client.ui.Frame; 030import com.google.gwt.user.client.ui.RootPanel; 031import de.novanic.eventservice.client.event.DomainEvent; 032import de.novanic.eventservice.client.event.RemoteEventServiceRuntimeException; 033import de.novanic.eventservice.client.event.service.EventService; 034import de.novanic.eventservice.client.event.service.EventServiceAsync; 035 036/** 037 * The {@link de.novanic.eventservice.client.connection.strategy.connector.ConnectionStrategyClientConnector} listens for occurred events ({@link de.novanic.eventservice.client.event.Event}) 038 * of the server side and has the task to encode / process the transferred events at the client side. 039 * 040 * The {@link de.novanic.eventservice.client.connection.strategy.connector.streaming.GWTStreamingClientConnector} is an 041 * GWT specific implementation of streaming. It implements the forever frame technique with a high number of GWT on-board methods. 042 * 043 * Streaming means that the connection is hold open for a specified time and when an event 044 * occurs, the answer / event is streamed directly to the client without closing and re-open the connection. The connection is 045 * closed and re-opened (by the client) when the configured max. waiting time is reached. 046 * 047 * @author sstrohschein 048 * <br>Date: 25.04.2010 049 * <br>Time: 23:02:50 050 */ 051public class GWTStreamingClientConnector extends DefaultStreamingClientConnector 052{ 053 private Frame myStreamingConnectorFrame; 054 private String myServiceURL; 055 056 /** 057 * Initializes the {@link de.novanic.eventservice.client.connection.strategy.connector.ConnectionStrategyClientConnector} with 058 * the {@link de.novanic.eventservice.client.event.service.EventServiceAsync}. 059 * 060 * That implementation prepares the processing of occurred, serialized events. 061 * @param anEventService the {@link de.novanic.eventservice.client.event.service.EventServiceAsync} 062 */ 063 public void init(EventServiceAsync anEventService) { 064 myServiceURL = ((ServiceDefTarget)anEventService).getServiceEntryPoint(); 065 initReceiveEventScript(this); 066 super.init(anEventService); 067 } 068 069 /** 070 * Deactivates the {@link de.novanic.eventservice.client.connection.strategy.connector.ConnectionStrategyClientConnector}. 071 * 072 * That implementation removes the forever frame, so the listening is stopped and cleared up. 073 */ 074 public void deactivate() { 075 if(myStreamingConnectorFrame != null) { 076 RootPanel.get().remove(myStreamingConnectorFrame); 077 myStreamingConnectorFrame = null; 078 } 079 } 080 081 /** 082 * Initializes or refreshes the forever frame. 083 */ 084 private void initStreamingConnectorFrame() { 085 if(myStreamingConnectorFrame == null) { 086 myStreamingConnectorFrame = new Frame(myServiceURL); 087 myStreamingConnectorFrame.setVisible(false); 088 RootPanel.get().add(myStreamingConnectorFrame); 089 } else { 090 //refresh / restart the connection 091 myStreamingConnectorFrame.setUrl(myServiceURL); 092 } 093 } 094 095 /** 096 * De-serializes an occurred event with GWT serialization methods. 097 * @param anEvent event to de-serialize 098 * @return de-serialized event 099 */ 100 protected DomainEvent deserializeEvent(String anEvent) { 101 try { 102 SerializationStreamFactory theSerializationStreamFactory = GWT.create(EventService.class); 103 SerializationStreamReader theSerializationStreamReader = theSerializationStreamFactory.createStreamReader(anEvent); 104 return (DomainEvent)theSerializationStreamReader.readObject(); 105 } catch(SerializationException e) { 106 throw new RemoteEventServiceRuntimeException("Error on de-serializing event \"" + anEvent + "\"!", e); 107 } 108 } 109 110 /** 111 * Initializes or refreshes the forever frame (see {@link GWTStreamingClientConnector#initStreamingConnectorFrame()}). 112 */ 113 protected void listen() { 114 initStreamingConnectorFrame(); 115 } 116 117 /** 118 * Initializes the processing of occurring events. 119 * @param aThisReference reference 120 */ 121 private native void initReceiveEventScript(DefaultStreamingClientConnector aThisReference) /*-{ 122 $wnd.receiveEvent = function(anEvent) { aThisReference.@de.novanic.eventservice.client.connection.strategy.connector.streaming.GWTStreamingClientConnector::receiveEvent(Ljava/lang/String;)(anEvent) }; 123 }-*/; 124}