Class 在Dart类中处理回调
我的dart应用程序正在侦听套接字我想在Class 在Dart类中处理回调,class,sockets,callback,dart,Class,Sockets,Callback,Dart,我的dart应用程序正在侦听套接字我想在dataHandler事件中处理后,在命令(…)函数上返回套接字应答 import 'dart:io'; import 'dart:async'; class TeamSpeak3{ Socket socket; String command; String _ip; int _port; TeamSpeak3(String ip, int port) { this._ip = ip;
dataHandler
事件中处理后,在命令(…)
函数上返回套接字应答
import 'dart:io';
import 'dart:async';
class TeamSpeak3{
Socket socket;
String command;
String _ip;
int _port;
TeamSpeak3(String ip, int port) {
this._ip = ip;
this._port = port;
}
Future<int> connect() async {
await Socket.connect(_ip, _port)
.then((Socket sock) {
socket = sock;
socket.listen(
dataHandler,
onError: errorHandler,
onDone: doneHandler,
cancelOnError: false);
}).catchError((AsyncError e) {
print("Connection failed: $e");
exit(1);
});
socket.done;
return 1;
}
void auth(String name, String pass){
socket.write("login $name $pass\n");
}
void send(String cmd){
command = cmd;
socket.write('$cmd\n');
//return reply from dataHandler
}
void dataHandler(data){
var reply = new String.fromCharCodes(data).trim();
//return $reply on the send function
}
void errorHandler(error, StackTrace trace){
print(error);
}
void doneHandler(){
print("Connection termiated!");
socket.destroy();
exit(0);
}
}
导入'dart:io';
导入“dart:async”;
班集体演讲3{
插座;
字符串命令;
字符串ip;
国际港口;
TeamSpeak3(字符串ip,内部端口){
这个。_ip=ip;
这个。_port=port;
}
Future connect()异步{
等待套接字。连接(\u ip,\u端口)
.然后((插座插座){
插座=插座;
听我说(
数据处理程序,
onError:errorHandler,
onDone:doneHandler,
取消者错误:false);
}).catchError((异步错误e){
打印(“连接失败:$e”);
出口(1);
});
socket.done;
返回1;
}
void auth(字符串名称、字符串传递){
socket.write(“login$name$pass\n”);
}
无效发送(字符串cmd){
command=cmd;
socket.write(“$cmd\n”);
//从dataHandler返回回复
}
无效数据处理程序(数据){
var reply=new String.fromCharCodes(data.trim();
//在send函数中返回$reply
}
无效错误处理程序(错误,堆栈跟踪){
打印(错误);
}
void doneHandler(){
打印(“连接终止!”);
socket.destroy();
出口(0);
}
}
首先,您无法确定发送的整个响应是否在一个数据包中到达,因此您可能没有完整的响应。
让我们假设您这样做了(否则您将不得不在dataHandler
中进行更多处理,以便在交付响应之前收集响应)
允许在将来发生某件事情时调用回调的规范方法是返回future
。您还需要一种方法来完成未来,因此您需要创建一个完成器
,并将其存储到需要时。因为你可能会做更多的发送,你需要记住不止一个完成符。所以,总而言之,我将这样写:
Queue<Completer<String>> _queue = Queue();
Future<String> send(String cmd){
socket.writeln(cmd);
var completer = new Completer<String>();
_queue.add(completer);
return completer.future;
}
void _dataHandler(data){
var reply = new String.fromCharCodes(data).trim();
// Add some sanity checking here. Make sure you have the entire response before
// executing the code below.
_queue.removeFirst().complete(reply);
}
Queue\u Queue=Queue();
未来发送(字符串cmd){
socket.writeln(cmd);
var completer=new completer();
_添加(完成符);
返回completer.future;
}
void\u数据处理程序(数据){
var reply=new String.fromCharCodes(data.trim();
//在此处添加一些健全性检查。确保在开始之前有完整的响应
//执行下面的代码。
_queue.removeFirst().complete(reply);
}
(我将
\u dataHandler
设为私有,因为您可能不希望调用send
的用户也能够调用dataHandler
).要将哪个回调传递给哪个类或函数?@creativecreateormabenotsocket。write
将某些内容写入socket,然后由数据处理程序处理输出,我需要将其作为send
的返回值传递,谢谢您的回答,但它给了我以下错误:未处理的异常:错误状态:无元素#0 ListQueue.removeFirst(dart:collection/queue.dart:793:25)#1 TeamSpeak3.\u dataHandler(file:///D:/Documents/PhpstormProjects/TS3Bot/lib/ts3.dart:67:16)
调试后:如果(_queue.isEmpty){print(“Empty”)}
这表明是emptynvm,我解决的问题是连接太多会触发服务器的响应。您好,我再次遇到调用函数的问题,该函数将触发数据处理程序内的另一个服务器响应,即:客户端发送到bot!帮助
机器人应该回复我来帮助你
。但是行为是这样的:如果我调用调用调用中的另一个函数(以获取更多客户机信息),第一个回复会被卡住,第二个回复会发送两次,第三个回复就可以了。完整源代码: