package io.muoncore.transport.sharedsocket.server; import io.muoncore.channel.ChannelConnection; import io.muoncore.codec.Codecs; import io.muoncore.message.MuonInboundMessage; import io.muoncore.message.MuonMessage; import io.muoncore.message.MuonMessageBuilder; import io.muoncore.message.MuonOutboundMessage; import io.muoncore.protocol.ServerStacks; import io.muoncore.transport.sharedsocket.client.SharedSocketRouter; import io.muoncore.transport.sharedsocket.client.messages.SharedChannelInboundMessage; import io.muoncore.transport.sharedsocket.client.messages.SharedChannelOutboundMessage; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.HashMap; import java.util.Map; /** * The concrete muon socket, acts as the multipler/ server router. */ public class SharedSocketServerChannel implements ChannelConnection<MuonInboundMessage, MuonOutboundMessage> { private Logger logger = LoggerFactory.getLogger(SharedSocketServerChannel.class); private ChannelFunction<MuonOutboundMessage> outboundFunc; private ServerStacks stacks; private Codecs codecs; private Map<String, ChannelConnection<MuonInboundMessage, MuonOutboundMessage>> localConnections = new HashMap<>(); public SharedSocketServerChannel(ServerStacks stacks, Codecs codecs) { this.codecs = codecs; this.stacks = stacks; } @Override public void receive(ChannelFunction<MuonOutboundMessage> function) { this.outboundFunc = function; } @Override public void send(MuonInboundMessage message) { if (message == null) { return; } if (message.getChannelOperation() == MuonMessage.ChannelOperation.closed) { logger.debug("Received a channel op closed message " + message); shutdown(); return; } SharedChannelInboundMessage msg = codecs.decode(message.getPayload(), message.getContentType(), SharedChannelInboundMessage.class); ChannelConnection<MuonInboundMessage, MuonOutboundMessage> connection = getConnectionToProtocol(msg); connection.send(msg.getMessage()); } private ChannelConnection<MuonInboundMessage, MuonOutboundMessage> getConnectionToProtocol(SharedChannelInboundMessage msg) { ChannelConnection<MuonInboundMessage, MuonOutboundMessage> protocolConnection = localConnections.get(msg.getChannelId()); if (protocolConnection == null) { protocolConnection = stacks.openServerChannel(msg.getMessage().getProtocol()); protocolConnection.receive(arg -> { if (arg == null || arg.getChannelOperation() == MuonMessage.ChannelOperation.closed) { shutdown(); return; } SharedChannelOutboundMessage sharedMsg = new SharedChannelOutboundMessage(msg.getChannelId(), arg); Codecs.EncodingResult result = codecs.encode(sharedMsg, new String[] { "application/json"}); MuonOutboundMessage outMsg = MuonMessageBuilder.fromService(arg.getSourceServiceName()) .contentType(result.getContentType()) .payload(result.getPayload()) .protocol(SharedSocketRouter.PROTOCOL) .step("message") .toService(arg.getTargetServiceName()).build(); outboundFunc.apply(outMsg); }); localConnections.put(msg.getChannelId(), protocolConnection); } return protocolConnection; } @Override public void shutdown() { //TODO, handle this, closing all sockets and protocol connections.. } }