/***************************************************************************** * Copyright 2013 Olivier Croquette <ocroquette@free.fr> * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ****************************************************************************/ package org.magnum.soda.server.wamp.client; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.UUID; import org.magnum.soda.msg.Msg; import org.magnum.soda.server.wamp.common.Channel; import org.magnum.soda.server.wamp.messages.CallErrorMessage; import org.magnum.soda.server.wamp.messages.CallMessage; import org.magnum.soda.server.wamp.messages.CallResultMessage; import org.magnum.soda.server.wamp.messages.EventMessage; import org.magnum.soda.server.wamp.messages.Message; import org.magnum.soda.server.wamp.messages.MessageMapper; import org.magnum.soda.server.wamp.messages.MessageType; import org.magnum.soda.server.wamp.messages.PublishMessage; import org.magnum.soda.server.wamp.messages.SubscribeMessage; import org.magnum.soda.server.wamp.messages.UnsubscribeMessage; import org.magnum.soda.server.wamp.messages.WelcomeMessage; public class WampClient { public boolean hasBeenWelcomed; public String serverIdent; public String sessionId; protected Channel outgoingChannel; Map<String, RpcResultReceiver> rpcResultReceivers; Map<String, EventReceiver> eventReceivers; public WampClient(Channel outgoingChannel) { init(); this.outgoingChannel = outgoingChannel; } protected void init() { rpcResultReceivers = new HashMap<String, RpcResultReceiver>(); eventReceivers = new HashMap<String, EventReceiver>(); } public void handleIncomingMessage(String jsonText) { Message message = MessageMapper.fromJson(jsonText); // System.out.println("handleIncomingMessage: " + jsonText); if ( message.getType() == MessageType.WELCOME ) { handleIncomingWelcomeMessage((WelcomeMessage)message); return; } if ( ! hasBeenWelcomed ) { String msg = "handleIncomingMessage: Cannot receive messages until we got a WELCOME message"; System.err.println(msg); throw new IllegalStateException("Client has not been welcomed yet"); } switch(message.getType()) { case CALLRESULT: handleIncomingCallResultMessage((CallResultMessage)message); break; case CALLERROR: handleIncomingCallErrorMessage((CallErrorMessage)message); break; case EVENT: handleIncomingEventMessage((EventMessage)message); break; default: // TODO logging System.err.println("ERROR: handleIncomingMessage doesn't know how to handle message type " + message.getType() ); } } protected void handleIncomingWelcomeMessage(WelcomeMessage message) { if ( hasBeenWelcomed ) throw new IllegalStateException("Client has already been welcomed"); checkNotNull("serverIdent", message.serverIdent); checkNotNull("sessionId", message.sessionId); serverIdent = message.serverIdent; sessionId = message.sessionId; hasBeenWelcomed = true; } protected void handleIncomingCallResultMessage(CallResultMessage message) { RpcResultReceiver receiver = null; synchronized(rpcResultReceivers) { receiver = rpcResultReceivers.get(message.callId); } if ( receiver == null ) { // TODO logging System.err.println("ERROR: handleIncomingCallResultMessage doesn't know a handler for this call " + message.callId); return; } receiver.setCallResultMessage(message); receiver.onSuccess(); } protected void handleIncomingCallErrorMessage(CallErrorMessage message) { RpcResultReceiver receiver = null; synchronized(rpcResultReceivers) { receiver = rpcResultReceivers.get(message.callId); } if ( receiver == null ) { // TODO logging System.err.println("ERROR: handleIncomingCallErrorMessage doesn't know a handler for this call " + message.callId); return; } receiver.setCallErrorMessage(message); receiver.onError(); } protected void handleIncomingEventMessage(EventMessage message) { EventReceiver receiver = null; synchronized(eventReceivers) { receiver = eventReceivers.get(message.topicUri); } if ( receiver == null ) { // TODO logging System.err.println("ERROR: handleIncomingEventMessage doesn't know a handler for this topic " + message.topicUri); return; } receiver.onReceive(message); } public void call(String procedureId, RpcResultReceiver rpcResultHandler) throws IOException { String callId = UUID.randomUUID().toString(); synchronized(rpcResultReceivers) { rpcResultReceivers.put(callId, rpcResultHandler); } outgoingChannel.handle(MessageMapper.toJson(new CallMessage(callId, procedureId))); } public <PayloadType> void call(String procedureId, RpcResultReceiver rpcResultHandler, PayloadType payload, Class<PayloadType> payloadType) throws IOException { String callId = UUID.randomUUID().toString(); synchronized(rpcResultReceivers) { rpcResultReceivers.put(callId, rpcResultHandler); } CallMessage msg = new CallMessage(callId, procedureId); msg.setPayload(payload, payloadType); outgoingChannel.handle(MessageMapper.toJson(msg)); } public void subscribe(String topicId, EventReceiver eventReceiver) throws IOException { synchronized (eventReceivers) { eventReceivers.put(topicId, eventReceiver); } outgoingChannel.handle(MessageMapper.toJson(new SubscribeMessage(topicId))); } public void unsubscribe(String topicId) throws IOException { synchronized (eventReceivers) { eventReceivers.remove(topicId); } outgoingChannel.handle(MessageMapper.toJson(new UnsubscribeMessage(topicId))); } public void publish(String topicId, Object payload) throws IOException { PublishMessage msg = new PublishMessage( topicId); msg.setPayload(payload); String json = MessageMapper.toJson(msg); outgoingChannel.handle(json); } public Object getServerIdent() { return serverIdent; } public Object getSessionId() { return sessionId; } protected void checkNotNull(String id, String s) { if ( s == null ) throw new IllegalArgumentException(id+" is null"); } public boolean hasBeenWelcomed() { return hasBeenWelcomed; } }