All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.twitter.finagle.websocket.Netty4.scala Maven / Gradle / Ivy

The newest version!
package com.twitter.finagle.websocket

import java.net.{SocketAddress, URI}

import com.twitter.finagle.client.Transporter
import com.twitter.finagle.netty4.{ByteBufConversion, Netty4Listener, Netty4Transporter}
import com.twitter.finagle.server.Listener
import com.twitter.finagle.transport.TransportContext
import com.twitter.finagle.{Address, Stack}
import io.github.cactacea.finasocket.Frame.{Binary, Ping, Pong, Text}
import io.github.cactacea.finasocket.{Frame, WebSocketClientHandler, WebSocketServerHandler}
import io.netty.channel.ChannelPipeline
import io.netty.handler.codec.http.websocketx._
import io.netty.handler.codec.http.{DefaultHttpHeaders, HttpClientCodec, HttpObjectAggregator, HttpServerCodec}

object Netty4 {
  import ByteBufConversion._

  private def serverPipeline(pipeline: ChannelPipeline): Unit = {
    pipeline.addLast("server", new HttpServerCodec)
    pipeline.addLast("aggregator", new HttpObjectAggregator(65536))
    pipeline.addLast("ws", new WebSocketServerHandler)
  }

  private def clientPipeline(handler: WebSocketClientHandler)(pipeline: ChannelPipeline): Unit = {
    pipeline.addLast("client", new HttpClientCodec())
    pipeline.addLast("aggregator", new HttpObjectAggregator(65536))
    pipeline.addLast("ws", handler)
  }

  def newListener(params: Stack.Params): Listener[Any, Any, TransportContext] =
    Netty4Listener(serverPipeline, params)

    def newTransporter(
                        wsScheme: String,
                        addr: SocketAddress,
                        params: Stack.Params): Transporter[Any, Any, TransportContext] = {

      val endpoint = params[Transporter.EndpointAddr].addr
      val uri = endpoint match {
        case Address.Inet(a, _) =>
          Some(new URI(s"${wsScheme}://${a.getHostName}:${a.getPort}"))
        case _ =>
          None
      }

      val httpHeaders = new DefaultHttpHeaders()
      val handShaker = WebSocketClientHandshakerFactory.newHandshaker(uri.get, WebSocketVersion.V13, null, false, httpHeaders, 1280000)
      val handler = new WebSocketClientHandler(handShaker)

      Netty4Transporter.raw(clientPipeline(handler), addr, params)

    }

  def fromNetty(m: Any): Frame = m match {
    case text: TextWebSocketFrame => Text(text.text())
    case cont: ContinuationWebSocketFrame => Text(cont.text())
    case binary: BinaryWebSocketFrame => Binary(byteBufAsBuf(binary.content()))
    case ping: PingWebSocketFrame => Binary(byteBufAsBuf(ping.content()))
    case pong: PongWebSocketFrame => Binary(byteBufAsBuf(pong.content()))
    case frame => throw new IllegalStateException(s"unknown frame: $frame")
  }

  def toNetty(frame: Frame): WebSocketFrame = frame match {
    case Text(message) => new TextWebSocketFrame(message)
    case Binary(buf) => new BinaryWebSocketFrame(bufAsByteBuf(buf))
    case Ping(buf) => new PingWebSocketFrame(bufAsByteBuf(buf))
    case Pong(buf) => new PongWebSocketFrame(bufAsByteBuf(buf))
  }

  def newHandshaker(uri: URI, headers: Map[String, String]): WebSocketClientHandshaker = {
    val httpHeaders = new DefaultHttpHeaders()
    headers.foreach({ case (k, v) => httpHeaders.add(k, v) })
    WebSocketClientHandshakerFactory.newHandshaker(uri, WebSocketVersion.V13, null, false, httpHeaders)
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy