driveChannel method
Implementation
Future<bool> driveChannel(Channel sock) async {
//
// 0. check channel state
//
ChannelStatus cs = sock.status;
if (cs == ChannelStatus.init) {
// preparing
return false;
} else if (cs == ChannelStatus.closed) {
// finished
return false;
}
// cs == opened
// cs == alive
Uint8List? data;
SocketAddress? remote;
SocketAddress? local;
//
// 1. try to receive
//
try {
Pair<Uint8List?, SocketAddress?> pair = await sock.receive(MSS);
data = pair.first;
remote = pair.second;
} on IOException catch (e) {
// print(e);
remote = sock.remoteAddress;
local = sock.localAddress;
ConnectionDelegate? gate = delegate;
Channel? cached;
if (gate == null || remote == null) {
// UDP channel may not connected,
// so no connection for it
cached = removeChannel(sock, remote: remote, local: local);
} else {
// remove channel and callback with connection
Connection? conn = getConnection(remote: remote, local: local);
cached = removeChannel(sock, remote: remote, local: local);
if (conn != null) {
await gate.onConnectionError(IOError(e), conn);
}
}
// close removed/error channels
if (cached == null || identical(cached, sock)) {} else {
await closeChannel(cached);
}
await closeChannel(sock);
return false;
}
if (remote == null || data == null) {
// received nothing
return false;
} else {
assert(data.isNotEmpty, 'data should not empty: $remote');
local = sock.localAddress;
}
//
// 2. get connection for processing received data
//
Connection? conn = await connect(remote: remote, local: local);
if (conn != null) {
await conn.onReceivedData(data);
}
return true;
}