Возможны ли не потоковые WebSockets в Scala? Не похоже на это - PullRequest
0 голосов
/ 28 апреля 2018

В JavaScript и Python, двух других языках, которые я часто использую на работе, очень легко настроить сервер (или клиент) WebSocket и отправлять / получать сообщения.

Например, посмотрите этот скопированный код из репозитория js WS . Для настройки Node-сервера WebSocket требуется только этот код:

const WebSocket = require('ws');

const wss = new WebSocket.Server({ port: 8080 });

wss.on('connection', function connection(ws) {
  ws.on('message', function incoming(message) {
    console.log('received: %s', message);
  });

  ws.send('something');
});

Затем я могу взять этот ws объект соединения, передать его какому-нибудь работнику и отправить обратно сообщения, когда захочу. Я могу, например, вручную ws.send("Batch 123 Complete"), и наш интерфейс отобразит это. Нет проблем.

В Scala, использую ли я http4s или akka-http, это кажется невозможным. Может быть, я слишком тупой, чтобы понять это (может быть!), Но я провел время в gitter http4s и читал тонны документов (fs2, стреляйте в меня), и, похоже, единственные решения Scala WS быть основанным на потоке: вы берете источник fromClient, источник toClient, подключаете их, и все. Вы не можете вручную сделать эквивалент Scala ws.send('some info!') со стороны сервера.

Очень добрый человек из блога http4s даже дошёл до того, что составил этот пример , чтобы попытаться помочь мне справиться с тем, что я делал, но в конечном итоге кажется, что это не так. Это очень большой запрос клиента -> настройка ответа сервера. Кажется, он не может просто отправлять сообщения клиенту, когда вам захочется.

Я что-то пропустил по этому поводу полностью? Надеюсь, у меня получилось, потому что я потратил пару дней на изучение сокетов http4s и fs2 на работе и предложил потоковую реализацию, основанную на планировщике fs2. Когда клиент открывает соединение с моим сервером WS, он порождает работника и отправляет обратно сообщения о состоянии каждую секунду, но мне это не нравится: / Обязательные изменяемые переменные в моем коде.

Буду очень признателен за любые советы или обсуждение.

1 Ответ

0 голосов
/ 28 апреля 2018

Я согласен, что пример HTTP4S безумен!

Это должен быть HTTP4S или Akka HTTP? Это легко сделать с помощью библиотеки Java-WebSocket:

val s = new WebSocketServer(address) {
  override def onOpen(webSocket: WebSocket,
                      clientHandshake: ClientHandshake): Unit = {
    // keep 'webSocket' around and push messages to it
  }

  override def onClose(webSocket: WebSocket,
                       code: Int,
                       reason: String,
                       remote: Boolean): Unit = 
    // remove the reference to 'webSocket'

  override def onMessage(webSocket: WebSocket, message: String): Unit =
    println("Received something from the client")

  override def onError(webSocket: WebSocket, e: Exception): Unit = ???

  override def onStart(): Unit = ???
}

https://github.com/TooTallNate/Java-WebSocket

...