132 lines
4.3 KiB
Java
132 lines
4.3 KiB
Java
/*
|
|
* Copyright (c) 2011 Tony Garnock-Jones. All rights reserved.
|
|
*/
|
|
|
|
package hop;
|
|
|
|
import java.io.IOException;
|
|
import java.io.OutputStream;
|
|
import java.net.Socket;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.UUID;
|
|
|
|
/**
|
|
*/
|
|
public class Relay implements Runnable, Node {
|
|
NodeContainer _container;
|
|
String _remoteName;
|
|
Socket _sock;
|
|
String _hostname;
|
|
int _port;
|
|
SexpReader _r;
|
|
OutputStream _output;
|
|
SexpWriter _w;
|
|
|
|
public Relay(NodeContainer container, String hostname) throws IOException, InterruptedException {
|
|
this(container, hostname, 5671);
|
|
}
|
|
|
|
public Relay(NodeContainer container, String hostname, int port) throws IOException, InterruptedException {
|
|
_container = container;
|
|
_remoteName = null;
|
|
_hostname = hostname;
|
|
_port = port;
|
|
_connect();
|
|
}
|
|
|
|
public String getRemoteName() {
|
|
return _remoteName;
|
|
}
|
|
|
|
public void _connect() throws IOException, InterruptedException {
|
|
_sock = new Socket(_hostname, _port);
|
|
_r = new SexpReader(_sock.getInputStream());
|
|
_output = _sock.getOutputStream();
|
|
_w = new SexpWriter(_output);
|
|
_login();
|
|
new Thread(this).start();
|
|
synchronized (this) {
|
|
while (_remoteName == null) {
|
|
this.wait();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void _login() throws IOException {
|
|
SexpList greeting = _r.readList();
|
|
if (!greeting.getBytes(0).getDataString().equals("hop")) {
|
|
throw new InvalidGreetingException(greeting);
|
|
}
|
|
|
|
_w.write(SexpMessage.subscribe(_container.getName(), null, null, null, null));
|
|
}
|
|
|
|
public void handle(Object message) {
|
|
try {
|
|
_w.write(message);
|
|
} catch (IOException ioe) {
|
|
ioe.printStackTrace();
|
|
System.err.print("Message to be written was: ");
|
|
try {
|
|
SexpWriter.write(System.err, message);
|
|
} catch (IOException ioe2) {
|
|
ioe2.printStackTrace();
|
|
}
|
|
System.err.println();
|
|
}
|
|
}
|
|
|
|
public void run() {
|
|
SexpList m = null;
|
|
try {
|
|
while (true) {
|
|
m = _r.readList();
|
|
if (m == null) {
|
|
break;
|
|
}
|
|
System.err.println("Received: " + m);
|
|
String selector = m.getBytes(0).getDataString();
|
|
if (selector.equals("post") && m.size() == 4) {
|
|
_container.send(m.getBytes(1).getDataString(), m.get(2));
|
|
} else if (selector.equals("subscribe") && m.size() == 6) {
|
|
if (_remoteName != null) {
|
|
System.err.println("Double bind attempted");
|
|
} else {
|
|
_remoteName = m.getBytes(1).getDataString();
|
|
synchronized (this) {
|
|
this.notifyAll();
|
|
}
|
|
if (_container.bind(_remoteName, this)) {
|
|
_container.post(m.getBytes(4).getDataString(), m.get(5), SexpMessage.subscribe_ok(_remoteName), null);
|
|
} else {
|
|
System.err.println("Bind failed: " + _remoteName);
|
|
}
|
|
}
|
|
} else if (selector.equals("unsubscribe") && m.size() == 2) {
|
|
if (!m.getBytes(1).getDataString().equals(_remoteName)) {
|
|
System.err.println("Unknown unbind attempted");
|
|
} else {
|
|
if (!_container.unbind(m.getBytes(1).getDataString())) {
|
|
System.err.println("Unbind failed: " + m.get(1));
|
|
}
|
|
}
|
|
} else {
|
|
System.err.print("Unknown message: ");
|
|
SexpWriter.write(System.err, m);
|
|
System.err.println();
|
|
}
|
|
}
|
|
} catch (IOException ioe) {
|
|
ioe.printStackTrace();
|
|
System.err.print("Most recent received message: ");
|
|
try {
|
|
SexpWriter.write(System.err, m);
|
|
} catch (IOException ioe2) {
|
|
ioe2.printStackTrace();
|
|
}
|
|
System.err.println();
|
|
}
|
|
}
|
|
}
|