我正在尝试在Dart中实现协议。
基本上,我需要创建一些类似于ask_for_help
(见下文)的方法。
这是我到目前为止的代码:
const int DEFAULT_TIMEOUT = 3;
class MySocket {
/// The host server
String _host;
/// The TCP port number
int _port;
/// The status of the socket (connected or not)
bool _isConnected = false;
/// The connection timeout
Duration _timeout;
/// The connected socket (if any, see [_isConnected])
Socket _socket;
/// Establish a connection with the [host] on given [port]
///
/// Throws a [SocketException] if connection cannot be established.
Future<void> connect(String host, int port,
{int timeout = DEFAULT_TIMEOUT}) async {
_host = host;
_port = port;
_timeout = Duration(seconds: timeout);
_socket = await Socket.connect(host, port, timeout: _timeout);
_isConnected = true;
_socket.listen(default_handler);
}
/// Send [cmd] command to the connected server
void send_request(String cmd) {
_socket.writeln(cmd);
}
/// Close the connection with the server
void close() {
_isConnected = false;
_socket.close();
}
void ask_for_help() {
var cmd = 'HELP';
send_request(cmd);
// Start listening to the socket
// Wait for a response
// Stop listening to the socket
// Consume response from the Stream
// Do something with that response (e.g print it on stdout)
}
}
void default_handler(Uint8List message) {
print('----- RESPONSE STARTS HERE -----');
print(String.fromCharCodes(message).trim());
print('----- RESPONSE ENDS HERE -----');
}
然后我有几个问题:
ask_for_help
监听套接字,直到它收到响应?关于第二个问题的说明:使用以上代码,当我发送多个请求且它们之间没有延迟时,所有响应都汇集在一起。这意味着我无法确定应该使用哪个函数来处理它。
欢迎任何建议。
答案 0 :(得分:0)
拥有一项进行实际通信的服务(即SocketService
)。当某人想通过套接字发送消息时,它可以调用消息。然后公开一个流对象,其他人可以订阅该流对象以侦听消息。
class SocketService {
SocketService _instance;
SocketService._();
factory SocketService() {
if (_instance == null) _instance = SocketService._();
return _instance;
}
final _streamController = StreamController.broadcast();
Stream get stream => _streamController.stream;
Future init() async {
// TODO: Initialize the socket connection
// TODO: Setup incoming messages to get routed to _onMessage
}
void _onMessage(dynamic message) {
_streamController.add(message);
}
StreamSubscription listen(void Function(dynamic) onMessage) {
return stream.listen(onMessage);
}
void sendMessage(dynamic message) {
// TODO: Send the message across the socket connection
}
void close() {
// TODO: Close the socket connection
_streamController.close();
}
}
其他地方:
// Listen for incoming messages
var subscription = SocketService().subscribe((msg) {
print(msg);
});
// Send a message
SocketService().sendMessage('This is a message');
特定于套接字的东西会有所不同,具体取决于您用来处理连接本身的软件包。上面将这种服务类作为过于简单的单例来实现,以使您理解要点,但是您可以自己使用所需的任何模式来实现此概念。
在子容器端,您还可以利用流转换来过滤除您实际感兴趣的消息以外的任何消息:
// Filter stream messages so only messages
// that are string objects get printed
var subscription = SocketService().stream.where((msg) => msg is String).listen(msg) {
print(msg);
});
传递给where
方法的过滤谓词可以实现您想要的任何条件。
仅供参考:如果您要在流和流操纵方面做很多事情,我强烈建议您使用rxdart软件包。与使用原始流相比,它使处理流更容易,更直观。