Как читать из TCP и писать в stdout?

Я не получаю простой пример потока в виде сказуса, который читается из TCP и записывается в std.

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. Я не думаю, что идиоматический способ сделать это, но он работает.

Ответ 1

Вам нужно передать 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 можно добавить ограничение на ++ и другие функции, которые используют ковариацию, чтобы удостовериться, что вычисляемая наименьшая верхняя граница не является чем-то бесполезным, например Any или Serializable. Это проделало бы долгий путь для предотвращения таких ошибок. В то же время убедитесь, что вы понимаете типы всех функций, с которыми работаете, что они делают, и как вы их склеиваете.