Migrate to simpler client/server communication model

This commit is contained in:
2015-06-21 17:39:24 +01:00
parent 931c219ebe
commit cccb76a03d
18 changed files with 201 additions and 261 deletions

View File

@@ -1,10 +1,10 @@
package com.github.boukefalos.lirc;
import base.Control;
import base.work.Listen;
public interface Lirc {
public void start();
// Required for Client / ClientListen to forward from separate Thread
public void input(Object object);
public interface Lirc extends Control {
public void register(Listen<Object> listen);
public void remove(Listen<Object> listen);
//public void send(String remote, String code);
}

View File

@@ -2,76 +2,59 @@ package com.github.boukefalos.lirc;
import java.util.Properties;
import org.picocontainer.Parameter;
import org.picocontainer.parameters.ConstantParameter;
import base.exception.LoaderException;
import base.loader.AbstractLoader;
import base.work.Work;
import com.github.boukefalos.lirc.client.LircTcpClient;
import com.github.boukefalos.lirc.implementation.LocalImplementation;
import com.github.boukefalos.lirc.implementation.TcpImplementation;
import com.github.boukefalos.lirc.implementation.UdpImplementation;
import com.github.boukefalos.lirc.server.LircServer;
import com.github.boukefalos.lirc.server.LircTcpServer;
import com.github.boukefalos.lirc.server.LircUdpServer;
import com.github.boukefalos.lirc.implementation.Local;
import com.github.boukefalos.lirc.implementation.Remote;
public class Loader extends AbstractLoader {
public class Loader extends AbstractLoader<Loader> {
protected static final String PROPERTIES_FILE = "lirc.properties";
public Loader(Properties properties) {
public Loader(Properties properties) throws LoaderException {
super();
/* Add implementation */
switch (properties.getProperty("implementation")) {
case "local":
pico.addComponent(LocalImplementation.class);
pico.addComponent(Local.class);
break;
case "remote":
//pico.addComponent(Remote.class);
break;
}
pico.addComponent(Remote.class);
/* Add protocol */
if (properties.getProperty("protocol") != null) {
switch (properties.getProperty("protocol")) {
case "tcp":
pico.addComponent(TcpImplementation.class, TcpImplementation.class, new Parameter[]{
new ConstantParameter(properties.getProperty("remote.host")),
new ConstantParameter(Integer.valueOf(properties.getProperty("remote.port")))});
break;
case "udp":
pico.addComponent(UdpImplementation.class, UdpImplementation.class, new Parameter[] {
new ConstantParameter(properties.getProperty("remote.host")),
new ConstantParameter(Integer.valueOf(properties.getProperty("remote.port")))});
break;
}
/* Add remote forwarder implementation */
try {
String protocol = properties.getOrDefault("server.protocol", "tcp").toString();
String implementation = properties.getOrDefault("tcp.implementation", "socket").toString();
int port = Integer.valueOf(properties.getProperty("remote.port"));
addForwarder(protocol, implementation, port);
} catch (NumberFormatException e) {
throw new LoaderException("Failed to parse remote.port");
}
break;
}
/* Add server */
if (properties.getProperty("server") != null) {
switch (properties.getProperty("server.protocol")) {
case "tcp":
pico.addComponent(LircTcpServer.class, LircTcpServer.class, new Parameter[]{
new ConstantParameter(getLirc()),
new ConstantParameter(Integer.valueOf(properties.getProperty("server.port"))),
new ConstantParameter(LircTcpClient.class)});
break;
case "udp":
pico.addComponent(LircUdpServer.class, LircUdpServer.class, new Parameter[]{
new ConstantParameter(getLirc()),
new ConstantParameter(Integer.valueOf(properties.getProperty("server.port")))});
}
pico.addComponent(Server.class);
/* Add sender implementation */
try {
String protocol = properties.getOrDefault("server.protocol", "tcp").toString();
String implementation = properties.getOrDefault("tcp.implementation", "socket").toString();
int port = Integer.valueOf(properties.getProperty("server.port"));
addSender(protocol, implementation, "localhost", port);
} catch (NumberFormatException e) {
throw new LoaderException("Failed to parse server.port");
}
}
}
public Lirc getLirc() {
public Lirc getLirc() {
return pico.getComponent(Lirc.class);
}
public Work getServer() {
return (Work) pico.getComponent(LircServer.class);
public Server getServer() {
return pico.getComponent(Server.class);
}
}

View File

@@ -1,4 +1,4 @@
package com.github.boukefalos.lirc.listen;
package com.github.boukefalos.lirc;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -13,17 +13,39 @@ import lirc.Lirc.DirectionButton;
import lirc.Lirc.Number;
import lirc.Lirc.NumberButton;
import lirc.Lirc.Signal;
import base.Control;
import base.exception.worker.ActivateException;
import base.exception.worker.DeactivateException;
import base.sender.Sender;
import base.work.Listen;
import com.github.boukefalos.lirc.LircButton;
import com.github.boukefalos.lirc.util.SignalObject;
public class ServerListen extends Listen<Object> {
public class Server extends Listen<Object> implements Control {
protected Lirc lirc;
protected Sender sender;
public ServerListen(Sender sender) {
public Server(Lirc lirc, Sender sender) {
this.lirc = lirc;
this.sender = sender;
lirc.register(this);
}
public void activate() throws ActivateException {
lirc.start();
sender.start();
super.activate();
}
public void deactivate() throws DeactivateException {
super.deactivate();
lirc.start();
sender.stop();
}
public void exit() {
lirc.exit();
sender.exit();
}
public void input(SignalObject<Object> signalObject) {
@@ -55,4 +77,4 @@ public class ServerListen extends Listen<Object> {
logger.error("Failed to send command");
}
}
}
}

View File

@@ -0,0 +1,5 @@
package com.github.boukefalos.lirc.button;
public interface RemoteButton {
}

View File

@@ -1,23 +0,0 @@
package com.github.boukefalos.lirc.client;
import java.nio.channels.SocketChannel;
import base.server.channel.TcpServerClient;
import com.github.boukefalos.lirc.server.LircTcpServer;
public class LircTcpClient extends TcpServerClient {
protected LircTcpServer server;
public LircTcpClient(LircTcpServer server, SocketChannel socketChannel, Integer bufferSize) {
super(server, socketChannel, bufferSize);
this.server = server;
}
public void receive(byte[] buffer) {
System.err.println(123);
System.err.println(new String(buffer).trim());
}
}

View File

@@ -33,12 +33,12 @@ import com.github.boukefalos.lirc.LircClient;
import com.github.boukefalos.lirc.util.Multiplexer;
import com.github.boukefalos.lirc.util.SignalObject;
public class LocalImplementation extends Listen<Object> implements Lirc {
public class Local extends Listen<Object> implements Lirc {
protected ArrayList<Listen<Object>> listenList;
protected Multiplexer<String> multiplexer;
protected LircClient lircClient;
public LocalImplementation() {
public Local() {
listenList = new ArrayList<Listen<Object>>();
lircClient = new LircClient(this);
multiplexer = new Multiplexer<String>();

View File

@@ -1,7 +1,8 @@
package com.github.boukefalos.server.helper;
package com.github.boukefalos.lirc.implementation;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import lirc.Lirc.Button;
import lirc.Lirc.Button.Type;
@@ -9,18 +10,40 @@ import lirc.Lirc.Color;
import lirc.Lirc.Direction;
import lirc.Lirc.Number;
import lirc.Lirc.Signal;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import base.receiver.Forwarder;
import base.server.forwarder.AbstractReceiver;
import base.work.Listen;
import com.github.boukefalos.lirc.Lirc;
import com.github.boukefalos.lirc.LircButton;
import com.github.boukefalos.lirc.util.SignalObject;
public class ServerHelper {
protected static Logger logger = LoggerFactory.getLogger(ServerHelper.class);
public class Remote extends AbstractReceiver implements Lirc {
protected ArrayList<Listen<Object>> listenList;
public static SignalObject<?> decode(Lirc lirc, byte[] buffer) {
public Remote(Forwarder forwarder) {
super(forwarder);
listenList = new ArrayList<Listen<Object>>();
}
public void register(Listen<Object> listen) {
listenList.add(listen);
}
public void remove(Listen<Object> listen) {
listenList.remove(listen);
}
public void receive(byte[] buffer) {
Object object = decode(buffer);
if (object != null) {
for (Listen<Object> listen : listenList) {
listen.add(object);
}
}
}
public SignalObject<?> decode(byte[] buffer) {
ByteArrayInputStream input = new ByteArrayInputStream(buffer);
try {
Button button = Button.parseDelimitedFrom(input);
@@ -47,4 +70,4 @@ public class ServerHelper {
}
return null;
}
}
}

View File

@@ -1,43 +0,0 @@
package com.github.boukefalos.lirc.implementation;
import java.util.ArrayList;
import base.exception.worker.ActivateException;
import base.server.socket.TcpClient; // Change to channel?
import base.work.Listen;
import com.github.boukefalos.lirc.Lirc;
import com.github.boukefalos.lirc.listen.ClientListen;
import com.github.boukefalos.server.helper.ServerHelper;
// Fix dual Receiver and Sender roles
public class TcpImplementation extends Listen<byte[]> implements Lirc {
protected TcpClient tcpClient;
protected ClientListen listen;
protected ArrayList<Listen<Object>> listenList;
public TcpImplementation(String host, int port) {
tcpClient = new TcpClient(host, port);
tcpClient.register(this);
listenList = new ArrayList<Listen<Object>>();
listen = new ClientListen(this);
}
public void activate() throws ActivateException {
listen.start();
super.activate();
}
public void input(byte[] buffer) {
Object object = ServerHelper.decode(this, buffer);
if (object != null) {
for (Listen<Object> listen : listenList) {
listen.add(object);
}
}
}
public void register(Listen<Object> listen) {
listenList.add(listen);
}
}

View File

@@ -1,34 +0,0 @@
package com.github.boukefalos.lirc.implementation;
import java.net.UnknownHostException;
import base.sender.UdpSender;
import base.work.Listen;
import com.github.boukefalos.lirc.Lirc;
public class UdpImplementation extends UdpSender implements Lirc {
public UdpImplementation(String host, int port) throws UnknownHostException {
super(host, port);
}
@Override
public void start() {
// TODO Auto-generated method stub
}
@Override
public void input(Object object) {
// TODO Auto-generated method stub
}
@Override
public void register(Listen<Object> listen) {
// TODO Auto-generated method stub
}
// add way to receive udp packets
}

View File

@@ -1,19 +0,0 @@
package com.github.boukefalos.lirc.listen;
import base.work.Listen;
import com.github.boukefalos.lirc.Lirc;
public class ClientListen extends Listen<Object> {
protected Lirc lirc;
public ClientListen(Lirc lirc) {
this.lirc = lirc;
}
public void input(Object object) {
lirc.input(object);
}
// forward send requests to sender
}

View File

@@ -1,5 +0,0 @@
package com.github.boukefalos.lirc.server;
public interface LircServer {
}

View File

@@ -1,30 +0,0 @@
package com.github.boukefalos.lirc.server;
import base.exception.worker.ActivateException;
import base.server.channel.TcpServer;
import com.github.boukefalos.lirc.Lirc;
import com.github.boukefalos.lirc.listen.ServerListen;
import com.github.boukefalos.server.helper.ServerHelper;
public class LircTcpServer extends TcpServer implements LircServer {
protected Lirc lirc;
protected ServerListen listen;
public LircTcpServer(Lirc lirc, int port, Class<?> clientClass) {
super(port, clientClass);
this.lirc = lirc;
listen = new ServerListen(this);
lirc.register(listen);
}
public void activate() throws ActivateException {
lirc.start();
listen.start();
super.activate();
}
public void receive(byte[] buffer) {
ServerHelper.decode(lirc, buffer);
}
}

View File

@@ -1,24 +0,0 @@
package com.github.boukefalos.lirc.server;
import base.server.datagram.UdpServer;
import com.github.boukefalos.lirc.Lirc;
import com.github.boukefalos.server.helper.ServerHelper;
public class LircUdpServer extends UdpServer implements LircServer {
protected Lirc lirc;
public LircUdpServer(Lirc lirc, int port) {
this(lirc, port, BUFFER_SIZE);
}
public LircUdpServer(Lirc lirc, int port, int bufferSize) {
super(port, bufferSize);
this.lirc = lirc;
this.bufferSize = bufferSize;
}
protected void receive(byte[] buffer) {
ServerHelper.decode(lirc, buffer);
}
}

View File

@@ -1,12 +0,0 @@
package com.github.boukefalos.server.helper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SenderHelper {
protected static Logger logger = LoggerFactory.getLogger(SenderHelper.class);
public static void send(String remote, String code) {
}
}

View File

@@ -6,7 +6,7 @@ import base.work.Listen;
import com.github.boukefalos.lirc.Lirc;
import com.github.boukefalos.lirc.LircButton;
import com.github.boukefalos.lirc.implementation.LocalImplementation;
import com.github.boukefalos.lirc.implementation.Local;
import com.github.boukefalos.lirc.util.SignalObject;
public class TestLocal extends Listen<Object> {
@@ -21,12 +21,11 @@ public class TestLocal extends Listen<Object> {
protected Lirc lirc;
public TestLocal() {
lirc = new LocalImplementation();
lirc = new Local();
lirc.register(this);
}
public void activate() throws ActivateException {
logger.debug("Activate " + getClass().getSimpleName());
lirc.start();
super.activate();
}

View File

@@ -0,0 +1,52 @@
package test;
import java.util.Properties;
import lirc.Lirc.Signal;
import base.exception.LoaderException;
import base.exception.worker.ActivateException;
import base.work.Listen;
import com.github.boukefalos.lirc.Lirc;
import com.github.boukefalos.lirc.LircButton;
import com.github.boukefalos.lirc.Loader;
import com.github.boukefalos.lirc.Server;
import com.github.boukefalos.lirc.util.SignalObject;
public class TestRemoteImplementation extends Listen<Object> {
protected Lirc lirc;
public TestRemoteImplementation(Loader loader) {
lirc = loader.getLirc();
lirc.register(this);
}
public void activate() throws ActivateException {
lirc.start();
super.activate();
}
public void input(SignalObject<LircButton> lircButtonSignal) {
Object object = lircButtonSignal.object;
if (object instanceof LircButton) {
Signal signal = lircButtonSignal.signal;
LircButton lircButton = lircButtonSignal.object;
String code = lircButton.code;
logger.error(signal.name() + " : " + code + " @ " + lircButton.remote);
}
}
public static void main(Properties localProperties, Properties remoteProperties) throws LoaderException {
Loader localLoader = new Loader(localProperties);
Loader remoteLoader = new Loader(remoteProperties);
Server server = localLoader.getServer();
server.start();
new TestRemoteImplementation(remoteLoader).start();
try {
Thread.sleep(1000000);
} catch (InterruptedException e) {}
}
}

View File

@@ -0,0 +1,23 @@
package test;
import java.util.Properties;
import base.exception.LoaderException;
public class TestTcpImplementation {
public static void main(String[] args) throws LoaderException {
Properties localProperties = new Properties();
localProperties.setProperty("implementation", "local");
localProperties.setProperty("server", "true");
localProperties.setProperty("server.port", "8883");
localProperties.setProperty("server.protocol", "tcp");
Properties remoteProperties = new Properties();
remoteProperties.setProperty("implementation", "remote");
remoteProperties.setProperty("protocol", "tcp");
remoteProperties.setProperty("remote.host", "localhost");
remoteProperties.setProperty("remote.port", "8883");
TestRemoteImplementation.main(localProperties, remoteProperties);
}
}

View File

@@ -0,0 +1,23 @@
package test;
import java.util.Properties;
import base.exception.LoaderException;
public class TestUdpImplementation {
public static void main(String[] args) throws LoaderException {
Properties localProperties = new Properties();
localProperties.setProperty("implementation", "local");
localProperties.setProperty("server", "true");
localProperties.setProperty("server.port", "8883");
localProperties.setProperty("server.protocol", "udp");
Properties remoteProperties = new Properties();
remoteProperties.setProperty("implementation", "remote");
remoteProperties.setProperty("protocol", "udp");
remoteProperties.setProperty("remote.host", "localhost");
remoteProperties.setProperty("remote.port", "8883");
TestRemoteImplementation.main(localProperties, remoteProperties);
}
}