如何从TCP读取并写入stdout?

Joe*_*ney 10 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
Run Code Online (Sandbox Code Playgroud)

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

我也试过各种安排使用to,总是用tcp.lift咒语得到一个Process[Connection, A],包括

tcp.server(addr, concurrentRequests = 1)(src) map (_ to tcp.lift(io.stdOutLines))
Run Code Online (Sandbox Code Playgroud)

甚至没有编译.

我是否需要wye将源和打印流一起使用?我就发现了一个例子原来拉请求tcp更换nio似乎表明这一点,但wye似乎不再上存在Process,因此混乱统治不幸.


编辑结果表明,除了Paul解释的类型问题之外,您还需要"手动"运行内部流程,例如通过执行p.map(_.run.run).run.run.我不认为这是执行此操作的惯用方法,但它确实有效.

pch*_*ano 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
Run Code Online (Sandbox Code Playgroud)

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

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