Class 在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;

我的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;
        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
).

要将哪个回调传递给哪个类或函数?@creativecreateormabenot
socket。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
!帮助
机器人应该回复
我来帮助你
。但是行为是这样的:如果我调用调用调用中的另一个函数(以获取更多客户机信息),第一个回复会被卡住,第二个回复会发送两次,第三个回复就可以了。完整源代码: