Warning: session_start(): open(/var/lib/php/sessions/sess_pn5ndo9u2cj1ifus9ravtamqpk, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
!7
import java.nio.*;
import java.nio.channels.*;
static long timeout = 30000+10000; // idle time + latency
static ConnectedInstances cI;
static ReliableSingleThread rst = new(r update);
static int theNumber;
static int port = 6000;
static Map dataMapper = synchroMap();
static ServerSocketChannel serverChannel;
static Selector selector;
sclass State {
S computerID = "?";
int countSeen = -1;
new LineBuffer lineBuffer; // TODO: max length
}
p {
cI = new ConnectedInstances;
cI.connected2.onChange(rst);
selector = Selector.open();
serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
InetSocketAddress sockAddr = new InetSocketAddress(port);
serverChannel.socket().bind(sockAddr);
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
thread "Server Accept Loop" { acceptLoop(); }
}
svoid cleanMeUp() ctex {
if (serverChannel != null)
serverChannel.close();
}
svoid acceptLoop ctex {
while licensed {
// wait for events
selector.select();
Iterator keys = selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = keys.next();
keys.remove();
if (!key.isValid()) continue;
pcall {
if (key.isAcceptable())
acceptOnSocket(key);
else if (key.isReadable())
readFromSocket(key);
}
}
}
}
//accept a connection made to this channel's socket
static void acceptOnSocket(SelectionKey key) throws IOException {
ServerSocketChannel serverChannel = cast key.channel();
SocketChannel channel = serverChannel.accept();
channel.configureBlocking(false);
Socket socket = channel.socket();
SocketAddress remoteAddr = socket.getRemoteSocketAddress();
print("Connected to: " + remoteAddr);
// register channel with selector for further IO
dataMapper.put(channel, new State);
channel.register(selector, SelectionKey.OP_READ);
}
static void readFromSocket(SelectionKey key) throws IOException {
SocketChannel channel = cast key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int numRead = channel.read(buffer);
if (numRead == -1) {
Socket socket = channel.socket();
SocketAddress remoteAddr = socket.getRemoteSocketAddress();
print("Connection closed by client: " + remoteAddr);
State state = dataMapper.get(channel);
if (state != null && state.computerID != null)
cI.lostConnection(state.computerID);
dataMapper.remove(channel);
channel.close();
key.cancel();
ret;
}
S s = new String(buffer.array(), 0, numRead);
print("Got data from client: " + s);
final State state = dataMapper.get(channel);
if (state != null)
state.lineBuffer.append(s, voidfunc(S line) {
new Matches m;
if (jmatch(line, "computerID=*", m)) {
if (state.computerID != null || !possibleComputerID($1)) ret;
state.computerID = $1;
cI.gotConnection(state.computerID);
}
});
}
html { ret "Use port " + port; }
svoid sendNumber(SocketChannel socket) ctex {
State s = dataMapper.get(socket);
if (s != null && theNumber != s.countSeen) {
s.countSeen = theNumber;
print("Sending number to " + s.computerID + ": " + theNumber);
socket.write(ByteBuffer.wrap(toUtf8(theNumber + "\n")));
}
}
svoid update {
print("OS Instances update");
if (empty(dataMapper)) ret;
int value = cI.value();
//if (value == theNumber) ret;
theNumber = value;
for (SocketChannel socket : keysList(dataMapper)) pcall {
sendNumber(socket);
}
print("OS Instances update done");
}