Java http上的Akka对象流

Java http上的Akka对象流,java,stream,akka,akka-stream,Java,Stream,Akka,Akka Stream,我有一段代码(见下文)生成了一个服务器,它回显它从端口6001接收到的每一个ByteString流。该示例还定义了一个客户端,该客户端连接到服务器并发送一个ByteString流,其中包含从字母“a”到“z”的字符列表 我在这一点上的问题是,akka是否提供了一种发送和接收对象流的方法,而不是http上的ByStreams?例如,类客户端的对象 如果是这样,我如何发送和接收这样的对象流?你能给我一个片段,说明如何执行它吗 Akka文档对于非玩具示例来说不是用户友好的 谢谢你的帮助 公共级TcpE

我有一段代码(见下文)生成了一个服务器,它回显它从端口6001接收到的每一个ByteString流。该示例还定义了一个客户端,该客户端连接到服务器并发送一个ByteString流,其中包含从字母“a”到“z”的字符列表

我在这一点上的问题是,akka是否提供了一种发送和接收对象流的方法,而不是http上的ByStreams?例如,类客户端的对象

如果是这样,我如何发送和接收这样的对象流?你能给我一个片段,说明如何执行它吗

Akka文档对于非玩具示例来说不是用户友好的

谢谢你的帮助

公共级TcpEcho{

/**
 * Use without parameters to start both client and server.
 *
 * Use parameters `server 0.0.0.0 6001` to start server listening on port
 * 6001.
 *
 * Use parameters `client 127.0.0.1 6001` to start client connecting to
 * server on 127.0.0.1:6001.
 *
 */
public static void main(String[] args) throws IOException {
    if (args.length == 0) {
        ActorSystem system = ActorSystem.create("ClientAndServer");
        InetSocketAddress serverAddress = new InetSocketAddress("127.0.0.1", 6000);
        server(system, serverAddress);
        client(system, serverAddress);
    } else {
        InetSocketAddress serverAddress;
        if (args.length == 3) {
            serverAddress = new InetSocketAddress(args[1], Integer.valueOf(args[2]));
        } else {
            serverAddress = new InetSocketAddress("127.0.0.1", 6000);
        }
        if (args[0].equals("server")) {
            ActorSystem system = ActorSystem.create("Server");
            server(system, serverAddress);
        } else if (args[0].equals("client")) {
            ActorSystem system = ActorSystem.create("Client");
            client(system, serverAddress);
        }
    }
}

public static void server(ActorSystem system, InetSocketAddress serverAddress) {
    final ActorMaterializer materializer = ActorMaterializer.create(system);

    final Sink<IncomingConnection, CompletionStage<Done>> handler = Sink.foreach(conn -> {
        System.out.println("Client connected from: " + conn.remoteAddress());
        conn.handleWith(Flow.<ByteString> create(), materializer);
    });

    final CompletionStage<ServerBinding> bindingFuture = Tcp.get(system)
            .bind(serverAddress.getHostString(), serverAddress.getPort()).to(handler).run(materializer);

    bindingFuture.whenComplete((binding, throwable) -> {
        System.out.println("Server started, listening on: " + binding.localAddress());
    });

    bindingFuture.exceptionally(e -> {
        System.err.println("Server could not bind to " + serverAddress + " : " + e.getMessage());
        system.terminate();
        return null;
    });

}

public static void client(ActorSystem system, InetSocketAddress serverAddress) {
    final ActorMaterializer materializer = ActorMaterializer.create(system);

    final List<ByteString> testInput = new ArrayList<>();
    for (char c = 'a'; c <= 'z'; c++) {
        testInput.add(ByteString.fromString(String.valueOf(c)));
    }

    Source<ByteString, NotUsed> responseStream = Source.from(testInput)
            .via(Tcp.get(system).outgoingConnection(serverAddress.getHostString(), serverAddress.getPort()));

    CompletionStage<ByteString> result = responseStream.runFold(ByteString.empty(), (acc, in) -> acc.concat(in),
            materializer);

    result.whenComplete((success, failure) -> {

        if (failure != null) {
            System.err.println("Failure: " + failure.getMessage());
        } else {
            System.out.println("Result: " + success.utf8String());
        }
        System.out.println("Shutting down client");
        system.terminate();

    });
}
/**
*在不带参数的情况下使用可同时启动客户端和服务器。
*
*使用参数“服务器0.0.0.0 6001”在端口上启动服务器侦听
* 6001.
*
*使用参数'client 127.0.0.1 6001'启动客户端连接到
*127.0.0.1:6001上的服务器。
*
*/
公共静态void main(字符串[]args)引发IOException{
如果(args.length==0){
ActorSystem=ActorSystem.create(“ClientAndServer”);
InetSocketAddress serverAddress=新的InetSocketAddress(“127.0.0.1”,6000);
服务器(系统、服务器地址);
客户端(系统、服务器地址);
}否则{
InetSocketAddress服务器地址;
如果(args.length==3){
serverAddress=新的InetSocketAddress(args[1],Integer.valueOf(args[2]);
}否则{
serverAddress=新的InetSocketAddress(“127.0.0.1”,6000);
}
if(args[0].equals(“服务器”)){
ActorSystem=ActorSystem.create(“服务器”);
服务器(系统、服务器地址);
}else if(args[0].equals(“客户端”)){
ActorSystem=ActorSystem.create(“客户端”);
客户端(系统、服务器地址);
}
}
}
公共静态void服务器(ActorSystem系统,InetSocketAddress服务器地址){
最终ActorMaterializer-materializer=ActorMaterializer.create(系统);
最终接收器处理程序=Sink.foreach(conn->{
System.out.println(“客户端连接自:+conn.remoteAddress());
conn.handleWith(Flow.create(),materializer);
});
final CompletionStage bindingFuture=Tcp.get(系统)
.bind(serverAddress.getHostString(),serverAddress.getPort()).to(handler.run(materializer);
bindingFuture.whenComplete((绑定,可丢弃)->{
System.out.println(“服务器已启动,正在侦听:+binding.localAddress());
});
绑定未来。例外情况下(e->{
System.err.println(“服务器无法绑定到”+serverAddress+:“+e.getMessage());
系统终止();
返回null;
});
}
公共静态无效客户端(ActorSystem系统,InetSocketAddress服务器地址){
最终ActorMaterializer-materializer=ActorMaterializer.create(系统);
最终列表testInput=新的ArrayList();
对于(字符c='a';c acc.concat(in),
物化器);
结果。完成时(成功、失败)->{
if(失败!=null){
System.err.println(“Failure:+Failure.getMessage());
}否则{
System.out.println(“结果:+success.utf8String());
}
System.out.println(“关闭客户端”);
系统终止();
});
}

}
akka.stream.{javadsl,scaladsl}.Framing
包含帮助您构建一致消息的实用程序。例如,您可以通过
Framing.simpleFramingProtocolEncoder(maxLength)
发送消息,以自动向其添加长度信息。在另一端,
Framing.simpleFramingProtocolDecoder(maxLength)
将负责根据消息所包含的长度信息对消息进行解码


如果你想操纵普通对象,你只需要在通过编码器发送它们之前将它们序列化为
ByteString
,然后在从解码器接收到它们的表示形式之后,从
ByteString
反序列化它们。

你知道如何创建Bidi流吗,我认为它或多或少可以做到,你要什么?我没看,但我会看的。在任何情况下,您是否有更好的想法/建议以代码片段的形式出现?谢谢