如何从TCP读取并写入stdout?

时间:2014-12-15 19:42:05

标签: scala scalaz-stream

我没有让一个简单的scalaz-stream示例运行,从TCP读取并写入std out。

val src = tcp.reads(1024)
val addr = new InetSocketAddress(12345)
val p = tcp.server(addr, concurrentRequests = 1) {
  src ++ tcp.lift(io.stdOutLines)
}
p.run.run

它只是坐在那里,而不是打印任何东西。

我还尝试使用to进行各种安排,始终使用tcp.lift咒语获得Process[Connection, A],包括

tcp.server(addr, concurrentRequests = 1)(src) map (_ to tcp.lift(io.stdOutLines))

甚至无法编译。

我是否需要wye源和打印流一起?我在tcp上找到nio替换wye的示例似乎表明了这一点,但Process上似乎不再存在p.map(_.run.run).run.run,因此不幸的是,混淆不幸


编辑结果表明,除了Paul解释的类型问题之外,还需要手动运行内部流程",例如通过执行{{1} }。我不认为这是执行此操作的惯用方式,但确实有效。

1 个答案:

答案 0 :(得分:5)

您需要将src传递到接收器以实际写入任何内容。我认为应该这样做:

import scalaz.stream.{io,tcp,text}
import scalaz.stream.tcp.syntax._

val p = tcp.server(addr, concurrentRequests = 1) { 
  tcp.reads(1024).pipe(text.utf8Decode) through tcp.lift(io.stdOutLines) 
}
p.run.run

表达式src ++ tcp.lift(io.stdOutLines)应该是类型错误。 tcp.reads(1024)的类型为Process[Connection,ByteVector]tcp.lift(io.stdOutLines)的类型为Process[Connection, String => Task[Unit]]。附加这两个过程是没有意义的,而且它检查的唯一原因是Process[+F[_],+O]的协方差。当您使用不相关的输出类型附加两个进程时,Scala会“帮助”推断Any

scalaz-stream的未来版本可能会在++和其他利用协方差的函数上添加约束,以确保计算得到的最小上限不会像Any或{{ 1}}。这对于防止这样的错误大有帮助。在此期间,请确保您了解您正在使用的所有功能的类型,它们的作用以及如何将它们粘在一起。