io.netty.channel.ChannelHandlerContext Scala Examples
The following examples show how to use io.netty.channel.ChannelHandlerContext.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example.
Example 1
Source File: MessageCodec.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.network import java.util import com.wavesplatform.crypto import com.wavesplatform.utils.ScorexLogging import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.ChannelHandlerContext import io.netty.handler.codec.MessageToMessageCodec import scala.util.{Failure, Success} @Sharable class MessageCodec(peerDatabase: PeerDatabase) extends MessageToMessageCodec[RawBytes, Message] with ScorexLogging { import BasicMessagesRepo.specsByCodes override def encode(ctx: ChannelHandlerContext, msg: Message, out: util.List[AnyRef]): Unit = msg match { // Have no spec case r: RawBytes => out.add(r) case LocalScoreChanged(score) => out.add(RawBytes(ScoreSpec.messageCode, ScoreSpec.serializeData(score))) case BlockForged(b) => out.add(RawBytes.fromBlock(b)) // With a spec case GetPeers => out.add(RawBytes(GetPeersSpec.messageCode, Array[Byte]())) case k: KnownPeers => out.add(RawBytes(PeersSpec.messageCode, PeersSpec.serializeData(k))) case g: GetBlock => out.add(RawBytes(GetBlockSpec.messageCode, GetBlockSpec.serializeData(g))) case m: MicroBlockInv => out.add(RawBytes(MicroBlockInvSpec.messageCode, MicroBlockInvSpec.serializeData(m))) case m: MicroBlockRequest => out.add(RawBytes(MicroBlockRequestSpec.messageCode, MicroBlockRequestSpec.serializeData(m))) // Version switch case gs: GetSignatures if isNewMsgsSupported(ctx) => out.add(RawBytes(GetBlockIdsSpec.messageCode, GetBlockIdsSpec.serializeData(gs))) case gs: GetSignatures if GetSignaturesSpec.isSupported(gs.signatures) => out.add(RawBytes(GetSignaturesSpec.messageCode, GetSignaturesSpec.serializeData(gs))) case s: Signatures => if (isNewMsgsSupported(ctx)) { out.add(RawBytes(BlockIdsSpec.messageCode, BlockIdsSpec.serializeData(s))) } else { val supported = s.signatures .dropWhile(_.arr.length != crypto.SignatureLength) .takeWhile(_.arr.length == crypto.SignatureLength) out.add(RawBytes(SignaturesSpec.messageCode, SignaturesSpec.serializeData(s.copy(signatures = supported)))) } case _ => throw new IllegalArgumentException(s"Can't send message $msg to $ctx (unsupported)") } override def decode(ctx: ChannelHandlerContext, msg: RawBytes, out: util.List[AnyRef]): Unit = { specsByCodes(msg.code).deserializeData(msg.data) match { case Success(x) => out.add(x) case Failure(e) => block(ctx, e) } } protected def block(ctx: ChannelHandlerContext, e: Throwable): Unit = { peerDatabase.blacklistAndClose(ctx.channel(), s"Invalid message. ${e.getMessage}") } private[this] def isNewMsgsSupported(ctx: ChannelHandlerContext): Boolean = { val (v1, v2, _) = ctx.channel().attr(HandshakeHandler.NodeVersionAttributeKey).get() v1 > 1 || (v1 == 1 && v2 >= 2) // >= 1.2.0 } }
Example 2
Source File: RBackendAuthHandler.scala From Spark-2.3.1 with Apache License 2.0 | 5 votes |
package org.apache.spark.api.r import java.io.{ByteArrayOutputStream, DataOutputStream} import java.nio.charset.StandardCharsets.UTF_8 import io.netty.channel.{Channel, ChannelHandlerContext, SimpleChannelInboundHandler} import org.apache.spark.internal.Logging import org.apache.spark.util.Utils private class RBackendAuthHandler(secret: String) extends SimpleChannelInboundHandler[Array[Byte]] with Logging { override def channelRead0(ctx: ChannelHandlerContext, msg: Array[Byte]): Unit = { // The R code adds a null terminator to serialized strings, so ignore it here. val clientSecret = new String(msg, 0, msg.length - 1, UTF_8) try { require(secret == clientSecret, "Auth secret mismatch.") ctx.pipeline().remove(this) writeReply("ok", ctx.channel()) } catch { case e: Exception => logInfo("Authentication failure.", e) writeReply("err", ctx.channel()) ctx.close() } } private def writeReply(reply: String, chan: Channel): Unit = { val out = new ByteArrayOutputStream() SerDe.writeString(new DataOutputStream(out), reply) chan.writeAndFlush(out.toByteArray()) } }
Example 3
Source File: HttpUtils.scala From Neutrino with Apache License 2.0 | 5 votes |
package com.ebay.neutrino.util import java.net.URI import com.ebay.neutrino.config.Host import com.typesafe.scalalogging.slf4j.StrictLogging import io.netty.buffer.Unpooled import io.netty.channel.ChannelHandlerContext import io.netty.handler.codec.http.HttpHeaders.{Names, Values} import io.netty.handler.codec.http._ import io.netty.util.CharsetUtil object HttpResponseUtils { import io.netty.handler.codec.http.HttpHeaderNames._ import io.netty.handler.codec.http.HttpVersion._ def error(status: HttpResponseStatus) = { // Allocate some memory for this val buffer = Unpooled.copiedBuffer(s"Failure: $status\r\n", CharsetUtil.UTF_8) // Package a response val response = new DefaultFullHttpResponse(HTTP_1_1, status, buffer) response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8") response } }
Example 4
Source File: MetricsAnnotationRegistryTest.scala From Neutrino with Apache License 2.0 | 5 votes |
package com.ebay.neutrino.health import com.codahale.metrics.annotation.{Gauge, Metered, Timed} import com.ebay.neutrino.handler.MetricsAnnotationRegistry import io.netty.channel.{ChannelHandlerContext, ChannelInboundHandler} import org.scalatest.{FlatSpec, Matchers} class MetricsAnnotationRegistryTest extends FlatSpec with Matchers { behavior of "Parsing Metrics Annotations" it should "skip class with no annotations" in { abstract class Test extends ChannelInboundHandler { override def channelRead(ctx: ChannelHandlerContext, msg: AnyRef) {} } // No annotations for the inbound-methods val registry = new MetricsAnnotationRegistry registry.getAnnotations(classOf[Test], "channelRegistered") shouldBe empty registry.getAnnotations(classOf[Test], "channelRead") shouldBe empty // Does not implement outbound interface; should fail trying to resolve a [NoSuchMethodException] should be thrownBy registry.getAnnotations(classOf[Test], "write") } it should "find only marked annotation" in { abstract class Test extends ChannelInboundHandler { @Timed @Gauge @Metered override def channelRegistered(ctx: ChannelHandlerContext) {} @Timed override def channelRead(ctx: ChannelHandlerContext, msg: AnyRef) {} } // No annotations for the inbound-methods val registry = new MetricsAnnotationRegistry registry.getAnnotations(classOf[Test], "channelRegistered").size shouldBe 3 registry.getAnnotations(classOf[Test], "channelRegistered")(0) shouldBe a [Timed] registry.getAnnotations(classOf[Test], "channelRegistered")(1) shouldBe a [Gauge] registry.getAnnotations(classOf[Test], "channelRegistered")(2) shouldBe a [Metered] registry.getAnnotations(classOf[Test], "channelRead").size shouldBe 1 registry.getAnnotations(classOf[Test], "channelRead")(0) shouldBe a [Timed] } it should "skip unrelated annotations" in { abstract class Test extends ChannelInboundHandler { override def channelRead(ctx: ChannelHandlerContext, msg: AnyRef) {} } val registry = new MetricsAnnotationRegistry registry.getAnnotations(classOf[Test], "channelRead") shouldBe empty } // registry cachings it should "cache subsequent invocations" in { //fail("Not implemented yet...") } }
Example 5
Source File: ExampleCloseHandler.scala From Neutrino with Apache License 2.0 | 5 votes |
package com.ebay.neutrino.handler import com.ebay.neutrino.NeutrinoRequest import com.typesafe.scalalogging.slf4j.StrictLogging import io.netty.buffer.Unpooled import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.{ChannelFutureListener, ChannelHandlerContext, ChannelInboundHandlerAdapter} import io.netty.handler.codec.http._ import io.netty.util.CharsetUtil @Sharable class ExampleCloseHandler extends ChannelInboundHandlerAdapter with StrictLogging { override def channelRead(ctx: ChannelHandlerContext, msg: AnyRef): Unit = msg match { case request: NeutrinoRequest if request.uri.startsWith("/close") => // Handle a 'close' request val status = HttpResponseStatus.OK val buffer = Unpooled.copiedBuffer(s"Handling /close request by closing connection.\r\n", CharsetUtil.UTF_8) val response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, buffer) // Set the content-type response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8") // Close the connection as soon as the error message is sent. ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE) case _ => // Fall through ctx.fireChannelRead(msg) } }
Example 6
Source File: HistoryReplier.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.network import com.wavesplatform.block.Block import com.wavesplatform.history.History import com.wavesplatform.network.HistoryReplier._ import com.wavesplatform.settings.SynchronizationSettings import com.wavesplatform.utils.ScorexLogging import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.{ChannelHandlerContext, ChannelInboundHandlerAdapter} import scala.concurrent.{ExecutionContext, Future} import scala.util.{Failure, Success} @Sharable class HistoryReplier(score: => BigInt, history: History, settings: SynchronizationSettings)(implicit ec: ExecutionContext) extends ChannelInboundHandlerAdapter with ScorexLogging { private def respondWith(ctx: ChannelHandlerContext, value: Future[Message]): Unit = value.onComplete { case Failure(e) => log.debug(s"${id(ctx)} Error processing request", e) case Success(value) => if (ctx.channel().isOpen) { ctx.writeAndFlush(value) } else { log.trace(s"${id(ctx)} Channel is closed") } } override def channelRead(ctx: ChannelHandlerContext, msg: AnyRef): Unit = msg match { case GetSignatures(otherSigs) => respondWith(ctx, Future(Signatures(history.blockIdsAfter(otherSigs, settings.maxRollback)))) case GetBlock(sig) => respondWith( ctx, Future(history.loadBlockBytes(sig)) .map { case Some((blockVersion, bytes)) => RawBytes(if (blockVersion < Block.ProtoBlockVersion) BlockSpec.messageCode else PBBlockSpec.messageCode, bytes) case _ => throw new NoSuchElementException(s"Error loading block $sig") } ) case MicroBlockRequest(microBlockId) => respondWith( ctx, Future(history.loadMicroBlock(microBlockId)).map { case Some(microBlock) => RawBytes.fromMicroBlock(MicroBlockResponse(microBlock, microBlockId)) case _ => throw new NoSuchElementException(s"Error loading microblock $microBlockId") } ) case _: Handshake => respondWith(ctx, Future(LocalScoreChanged(score))) case _ => super.channelRead(ctx, msg) } def cacheSizes: CacheSizes = CacheSizes(0, 0) } object HistoryReplier { case class CacheSizes(blocks: Long, microBlocks: Long) }
Example 7
Source File: MessageObserver.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.network import com.wavesplatform.block.Block import com.wavesplatform.transaction.Transaction import com.wavesplatform.utils.{Schedulers, ScorexLogging} import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.{Channel, ChannelHandlerContext, ChannelInboundHandlerAdapter} import monix.execution.schedulers.SchedulerService import monix.reactive.subjects.ConcurrentSubject @Sharable class MessageObserver extends ChannelInboundHandlerAdapter with ScorexLogging { private implicit val scheduler: SchedulerService = Schedulers.fixedPool(2, "message-observer") private val signatures = ConcurrentSubject.publish[(Channel, Signatures)] private val blocks = ConcurrentSubject.publish[(Channel, Block)] private val blockchainScores = ConcurrentSubject.publish[(Channel, BigInt)] private val microblockInvs = ConcurrentSubject.publish[(Channel, MicroBlockInv)] private val microblockResponses = ConcurrentSubject.publish[(Channel, MicroBlockResponse)] private val transactions = ConcurrentSubject.publish[(Channel, Transaction)] override def channelRead(ctx: ChannelHandlerContext, msg: AnyRef): Unit = msg match { case b: Block => blocks.onNext((ctx.channel(), b)) case sc: BigInt => blockchainScores.onNext((ctx.channel(), sc)) case s: Signatures => signatures.onNext((ctx.channel(), s)) case mbInv: MicroBlockInv => microblockInvs.onNext((ctx.channel(), mbInv)) case mb: MicroBlockResponse => microblockResponses.onNext((ctx.channel(), mb)) case tx: Transaction => transactions.onNext((ctx.channel(), tx)) case _ => super.channelRead(ctx, msg) } def shutdown(): Unit = { signatures.onComplete() blocks.onComplete() blockchainScores.onComplete() microblockInvs.onComplete() microblockResponses.onComplete() transactions.onComplete() } } object MessageObserver { type Messages = ( ChannelObservable[Signatures], ChannelObservable[Block], ChannelObservable[BigInt], ChannelObservable[MicroBlockInv], ChannelObservable[MicroBlockResponse], ChannelObservable[Transaction] ) def apply(): (MessageObserver, Messages) = { val mo = new MessageObserver() (mo, (mo.signatures, mo.blocks, mo.blockchainScores, mo.microblockInvs, mo.microblockResponses, mo.transactions)) } }
Example 8
Source File: PeerKey.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.network import java.net.{InetAddress, SocketAddress} import io.netty.channel.ChannelHandlerContext import io.netty.channel.embedded.EmbeddedChannel import io.netty.channel.socket.SocketChannel sealed trait PeerKey case object PeerKey { case class InetPeerKey(host: InetAddress, nonce: Long) extends PeerKey case class SocketPeerKey(host: SocketAddress, nonce: Long) extends PeerKey def apply(ctx: ChannelHandlerContext, nodeNonce: Long): Option[PeerKey] = ctx.channel() match { case x: SocketChannel => Option(x.remoteAddress()).map(_.getAddress).map(PeerKey.InetPeerKey(_, nodeNonce)) case x: EmbeddedChannel => Option(x.remoteAddress()).map(PeerKey.SocketPeerKey(_, nodeNonce)) case x => throw new IllegalArgumentException(s"Can't get PeerKey from ${id(ctx)}, $x") } }
Example 9
Source File: TrafficWatcher.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.network import com.wavesplatform.network.message.{Message => ScorexMessage} import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.{ChannelDuplexHandler, ChannelHandlerContext, ChannelPromise} import kamon.Kamon import kamon.metric.{Histogram, MeasurementUnit} @Sharable class TrafficWatcher extends ChannelDuplexHandler { import BasicMessagesRepo.specsByCodes private val outgoing: Map[ScorexMessage.MessageCode, Histogram] = specsByCodes.map { case (code, spec) => code -> createHistogram("outgoing", spec) } private val incoming: Map[ScorexMessage.MessageCode, Histogram] = specsByCodes.map { case (code, spec) => code -> createHistogram("incoming", spec) } private def createHistogram(dir: String, spec: BasicMessagesRepo.Spec): Histogram = Kamon .histogram("traffic", MeasurementUnit.information.bytes) .withTag("type", spec.messageName) .withTag("dir", dir) override def write(ctx: ChannelHandlerContext, msg: AnyRef, promise: ChannelPromise): Unit = { msg match { case x: RawBytes => outgoing.get(x.code).foreach(_.record(x.data.length)) case _ => } super.write(ctx, msg, promise) } override def channelRead(ctx: ChannelHandlerContext, msg: AnyRef): Unit = { msg match { case x: RawBytes => incoming.get(x.code).foreach(_.record(x.data.length)) case _ => } super.channelRead(ctx, msg) } }
Example 10
Source File: DiscardingHandler.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.network import com.wavesplatform.utils.{Schedulers, ScorexLogging} import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.{ChannelDuplexHandler, ChannelHandlerContext} import monix.execution.schedulers.SchedulerService import monix.reactive.Observable @Sharable class DiscardingHandler(blockchainReadiness: Observable[Boolean]) extends ChannelDuplexHandler with ScorexLogging { private implicit val scheduler: SchedulerService = Schedulers.fixedPool(2, "discarding-handler") private val lastReadiness = lastObserved(blockchainReadiness) override def channelRead(ctx: ChannelHandlerContext, msg: AnyRef): Unit = msg match { case RawBytes(code @ (TransactionSpec.messageCode | PBTransactionSpec.messageCode), _) if !lastReadiness().contains(true) => log.trace(s"${id(ctx)} Discarding incoming message $code") case _ => super.channelRead(ctx, msg) } }
Example 11
Source File: InboundConnectionFilter.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.network import java.net.{InetAddress, InetSocketAddress} import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.atomic.AtomicInteger import com.wavesplatform.utils.ScorexLogging import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.{ChannelFuture, ChannelHandlerContext} import io.netty.handler.ipfilter.AbstractRemoteAddressFilter @Sharable class InboundConnectionFilter(peerDatabase: PeerDatabase, maxInboundConnections: Int, maxConnectionsPerHost: Int) extends AbstractRemoteAddressFilter[InetSocketAddress] with ScorexLogging { private val inboundConnectionCount = new AtomicInteger(0) private val perHostConnectionCount = new ConcurrentHashMap[InetAddress, Int] private val emptyChannelFuture = null.asInstanceOf[ChannelFuture] private def dec(remoteAddress: InetAddress) = { inboundConnectionCount.decrementAndGet() log.trace(s"Number of inbound connections: ${inboundConnectionCount.get()}") perHostConnectionCount.compute(remoteAddress, (_, cnt) => cnt - 1) emptyChannelFuture } override def accept(ctx: ChannelHandlerContext, remoteAddress: InetSocketAddress): Boolean = Option(remoteAddress.getAddress) match { case None => log.debug(s"Can't obtain an address from $remoteAddress") false case Some(address) => val newTotal = inboundConnectionCount.incrementAndGet() val newCountPerHost = perHostConnectionCount.compute(address, (_, cnt) => Option(cnt).fold(1)(_ + 1)) val isBlacklisted = peerDatabase.blacklistedHosts.contains(address) val accepted = newTotal <= maxInboundConnections && newCountPerHost <= maxConnectionsPerHost && !isBlacklisted log.trace( s"Check inbound connection from $remoteAddress: new inbound total = $newTotal, " + s"connections with this host = $newCountPerHost, address ${if (isBlacklisted) "IS" else "is not"} blacklisted, " + s"${if (accepted) "is" else "is not"} accepted" ) accepted } override def channelAccepted(ctx: ChannelHandlerContext, remoteAddress: InetSocketAddress): Unit = ctx.channel().closeFuture().addListener((_: ChannelFuture) => Option(remoteAddress.getAddress).foreach(dec)) override def channelRejected(ctx: ChannelHandlerContext, remoteAddress: InetSocketAddress): ChannelFuture = Option(remoteAddress.getAddress).fold(emptyChannelFuture)(dec) }
Example 12
Source File: GrpcGatewayHandler.scala From grpcgateway with MIT License | 5 votes |
package grpcgateway.handlers import java.nio.charset.StandardCharsets import scalapb.GeneratedMessage import scalapb.json4s.JsonFormat import io.grpc.ManagedChannel import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.{ ChannelFutureListener, ChannelHandlerContext, ChannelInboundHandlerAdapter } import io.netty.handler.codec.http._ import scala.concurrent.{ ExecutionContext, Future } @Sharable abstract class GrpcGatewayHandler(channel: ManagedChannel)(implicit ec: ExecutionContext) extends ChannelInboundHandlerAdapter { def name: String def shutdown(): Unit = if (!channel.isShutdown) channel.shutdown() def supportsCall(method: HttpMethod, uri: String): Boolean def unaryCall(method: HttpMethod, uri: String, body: String): Future[GeneratedMessage] override def channelRead(ctx: ChannelHandlerContext, msg: scala.Any): Unit = { msg match { case req: FullHttpRequest => if (supportsCall(req.method(), req.uri())) { val body = req.content().toString(StandardCharsets.UTF_8) unaryCall(req.method(), req.uri(), body) .map(JsonFormat.toJsonString) .map(json => { buildFullHttpResponse( requestMsg = req, responseBody = json, responseStatus = HttpResponseStatus.OK, responseContentType = "application/json" ) }) .recover({ case err => val (body, status) = err match { case e: GatewayException => e.details -> GRPC_HTTP_CODE_MAP.getOrElse(e.code, HttpResponseStatus.INTERNAL_SERVER_ERROR) case _ => "Internal error" -> HttpResponseStatus.INTERNAL_SERVER_ERROR } buildFullHttpResponse( requestMsg = req, responseBody = body, responseStatus = status, responseContentType = "application/text" ) }).foreach(resp => { ctx.writeAndFlush(resp).addListener(ChannelFutureListener.CLOSE) }) } else { super.channelRead(ctx, msg) } case _ => super.channelRead(ctx, msg) } } }
Example 13
Source File: LegacyFrameCodec.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.network import java.util import com.google.common.cache.CacheBuilder import com.wavesplatform.block.Block import com.wavesplatform.common.utils.Base64 import com.wavesplatform.crypto import com.wavesplatform.network.message.Message._ import com.wavesplatform.transaction.Transaction import com.wavesplatform.utils.ScorexLogging import io.netty.buffer.ByteBuf import io.netty.buffer.Unpooled._ import io.netty.channel.ChannelHandlerContext import io.netty.handler.codec.{ByteToMessageCodec, DecoderException} import scala.concurrent.duration.FiniteDuration import scala.util.control.NonFatal class LegacyFrameCodec(peerDatabase: PeerDatabase, receivedTxsCacheTimeout: FiniteDuration) extends ByteToMessageCodec[Any] with ScorexLogging { import BasicMessagesRepo.specsByCodes import LegacyFrameCodec._ private val receivedTxsCache = CacheBuilder .newBuilder() .expireAfterWrite(receivedTxsCacheTimeout.length, receivedTxsCacheTimeout.unit) .build[String, Object]() override def exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable): Unit = cause match { case e: DecoderException => peerDatabase.blacklistAndClose(ctx.channel(), s"Corrupted message frame: $e") case _ => super.exceptionCaught(ctx, cause) } override def decode(ctx: ChannelHandlerContext, in: ByteBuf, out: util.List[AnyRef]): Unit = try { require(in.readInt() == Magic, "invalid magic number") val code = in.readByte() require(specsByCodes.contains(code), s"Unexpected message code $code") val spec = specsByCodes(code) val length = in.readInt() require(length <= spec.maxLength, s"${spec.messageName} message length $length exceeds ${spec.maxLength}") val dataBytes = new Array[Byte](length) val pushToPipeline = length == 0 || { val declaredChecksum = in.readSlice(ChecksumLength) in.readBytes(dataBytes) val rawChecksum = crypto.fastHash(dataBytes) val actualChecksum = wrappedBuffer(rawChecksum, 0, ChecksumLength) require(declaredChecksum.equals(actualChecksum), "invalid checksum") actualChecksum.release() spec != TransactionSpec || { val actualChecksumStr = Base64.encode(rawChecksum) if (receivedTxsCache.getIfPresent(actualChecksumStr) == null) { receivedTxsCache.put(actualChecksumStr, LegacyFrameCodec.dummy) true } else false } } if (pushToPipeline) out.add(RawBytes(code, dataBytes)) } catch { case NonFatal(e) => log.warn(s"${id(ctx)} Malformed network message", e) peerDatabase.blacklistAndClose(ctx.channel(), s"Malformed network message: $e") in.resetReaderIndex() // Cancels subsequent read tries, see Netty decode() documentation } override def encode(ctx: ChannelHandlerContext, msg1: Any, out: ByteBuf): Unit = { val msg = msg1 match { case rb: RawBytes => rb case tx: Transaction => RawBytes.fromTransaction(tx) case block: Block => RawBytes.fromBlock(block) case mb: MicroBlockResponse => RawBytes.fromMicroBlock(mb) } out.writeInt(Magic) out.writeByte(msg.code) if (msg.data.length > 0) { out.writeInt(msg.data.length) out.writeBytes(crypto.fastHash(msg.data), 0, ChecksumLength) out.writeBytes(msg.data) } else { out.writeInt(0) } } } object LegacyFrameCodec { val Magic = 0x12345678 private val dummy = new Object() }
Example 14
Source File: FatalErrorHandler.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.network import java.io.IOException import com.wavesplatform.utils.{ScorexLogging, forceStopApplication} import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.{ChannelHandlerContext, ChannelInboundHandlerAdapter} import scala.util.control.NonFatal @Sharable class FatalErrorHandler extends ChannelInboundHandlerAdapter with ScorexLogging { override def exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable): Unit = cause match { case ioe: IOException if ioe.getMessage == "Connection reset by peer" => // https://stackoverflow.com/q/9829531 // https://stackoverflow.com/q/1434451 log.trace(s"${id(ctx)} Connection reset by peer") case NonFatal(_) => log.debug(s"${id(ctx)} Exception caught", cause) case _ => new Thread(() => { log.error(s"${id(ctx)} Fatal error in channel, terminating application", cause) forceStopApplication() }, "waves-platform-shutdown-thread").start() } }
Example 15
Source File: PeerSynchronizer.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.network import java.net.InetSocketAddress import com.wavesplatform.utils.ScorexLogging import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.{ChannelHandlerContext, ChannelInboundHandlerAdapter} import scala.concurrent.duration.FiniteDuration class PeerSynchronizer(peerDatabase: PeerDatabase, peerRequestInterval: FiniteDuration) extends ChannelInboundHandlerAdapter with ScorexLogging { private var peersRequested = false private var declaredAddress = Option.empty[InetSocketAddress] def requestPeers(ctx: ChannelHandlerContext): Unit = if (ctx.channel().isActive) { peersRequested = true ctx.writeAndFlush(GetPeers) ctx.executor().schedule(peerRequestInterval) { requestPeers(ctx) } } override def channelRead(ctx: ChannelHandlerContext, msg: AnyRef): Unit = { declaredAddress.foreach(peerDatabase.touch) msg match { case hs: Handshake => val rda = for { rda <- hs.declaredAddress rdaAddress <- Option(rda.getAddress) ctxAddress <- ctx.remoteAddress.map(_.getAddress) if rdaAddress == ctxAddress } yield rda rda match { case None => log.debug(s"${id(ctx)} Declared address $rda does not match actual remote address ${ctx.remoteAddress.map(_.getAddress)}") case Some(x) => log.trace(s"${id(ctx)} Touching declared address") peerDatabase.touch(x) declaredAddress = Some(x) } requestPeers(ctx) super.channelRead(ctx, msg) case GetPeers => ctx.writeAndFlush(KnownPeers(peerDatabase.knownPeers.keys.toSeq)) case KnownPeers(peers) if peersRequested => peersRequested = false val (added, notAdded) = peers.partition(peerDatabase.addCandidate) log.trace(s"${id(ctx)} Added peers: ${format(added)}, not added peers: ${format(notAdded)}") case KnownPeers(peers) => log.trace(s"${id(ctx)} Got unexpected list of known peers containing ${peers.size} entries") case _ => super.channelRead(ctx, msg) } } private def format[T](xs: Iterable[T]): String = xs.mkString("[", ", ", "]") } object PeerSynchronizer { @Sharable class NoopPeerSynchronizer extends ChannelInboundHandlerAdapter { override def channelRead(ctx: ChannelHandlerContext, msg: AnyRef): Unit = { msg match { case GetPeers => case KnownPeers(_) => case _ => super.channelRead(ctx, msg) } } } val Disabled = new NoopPeerSynchronizer() }
Example 16
Source File: TrafficLogger.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.network import com.wavesplatform.block.Block import com.wavesplatform.block.serialization.BlockHeaderSerializer import com.wavesplatform.common.utils.Base64 import com.wavesplatform.network.message.{Message => ScorexMessage} import com.wavesplatform.transaction.Transaction import com.wavesplatform.utils.ScorexLogging import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.{ChannelDuplexHandler, ChannelHandlerContext, ChannelPromise} @Sharable class TrafficLogger(settings: TrafficLogger.Settings) extends ChannelDuplexHandler with ScorexLogging { import BasicMessagesRepo.specsByClasses private val codeOf: AnyRef => Option[Byte] = { val aux: PartialFunction[AnyRef, Byte] = { case x: RawBytes => x.code case _: Transaction => TransactionSpec.messageCode case _: BigInt | _: LocalScoreChanged => ScoreSpec.messageCode case _: Block | _: BlockForged => BlockSpec.messageCode case x: Message => specsByClasses(x.getClass).messageCode case _: Handshake => HandshakeSpec.messageCode } aux.lift } override def write(ctx: ChannelHandlerContext, msg: AnyRef, promise: ChannelPromise): Unit = { codeOf(msg).filterNot(settings.ignoreTxMessages).foreach { code => log.trace(s"${id(ctx)} <-- transmitted($code): ${stringify(msg)}") } super.write(ctx, msg, promise) } override def channelRead(ctx: ChannelHandlerContext, msg: AnyRef): Unit = { codeOf(msg).filterNot(settings.ignoreRxMessages).foreach { code => log.trace(s"${id(ctx)} --> received($code): ${stringify(msg)}") } super.channelRead(ctx, msg) } private def stringify(msg: Any): String = msg match { case tx: Transaction => tx.json().toString() case b: Block => s"${b.id()}, header: ${BlockHeaderSerializer.toJson(b.header, b.bytes().length, b.transactionData.length, b.signature).toString}" case RawBytes(_, data) => Base64.encode(data) case other => other.toString } } object TrafficLogger { case class Settings(ignoreTxMessages: Set[ScorexMessage.MessageCode], ignoreRxMessages: Set[ScorexMessage.MessageCode]) }
Example 17
Source File: HandshakeDecoderSpec.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.network import java.nio.charset.StandardCharsets import com.google.common.primitives.{Ints, Longs} import com.wavesplatform.{NoShrink, TransactionGen} import io.netty.buffer.Unpooled import io.netty.channel.embedded.EmbeddedChannel import io.netty.channel.{ChannelHandlerContext, ChannelInboundHandlerAdapter} import org.scalacheck.{Arbitrary, Gen} import org.scalamock.scalatest.MockFactory import org.scalatest.{FreeSpec, Matchers} import org.scalatestplus.scalacheck.{ScalaCheckPropertyChecks => PropertyChecks} class HandshakeDecoderSpec extends FreeSpec with Matchers with MockFactory with PropertyChecks with TransactionGen with NoShrink { "should read a handshake and remove itself from the pipeline" in { var mayBeDecodedHandshake: Option[Handshake] = None val channel = new EmbeddedChannel( new HandshakeDecoder(PeerDatabase.NoOp), new ChannelInboundHandlerAdapter { override def channelRead(ctx: ChannelHandlerContext, msg: Any): Unit = msg match { case x: Handshake => mayBeDecodedHandshake = Some(x) case _ => } } ) val origHandshake = new Handshake( applicationName = "wavesI", applicationVersion = (1, 2, 3), nodeName = "test", nodeNonce = 4, declaredAddress = None ) val buff = Unpooled.buffer origHandshake.encode(buff) buff.writeCharSequence("foo", StandardCharsets.UTF_8) channel.writeInbound(buff) mayBeDecodedHandshake should contain(origHandshake) } private val invalidHandshakeBytes: Gen[Array[Byte]] = { // To bypass situations where the appNameLength > whole buffer and HandshakeDecoder waits for next bytes val appName = "x" * Byte.MaxValue val nodeName = "y" * Byte.MaxValue val appNameBytes = appName.getBytes(StandardCharsets.UTF_8) val versionBytes = Array(1, 2, 3).flatMap(Ints.toByteArray) val nodeNameBytes = nodeName.getBytes(StandardCharsets.UTF_8) val nonceBytes = Longs.toByteArray(1) val timestampBytes = Longs.toByteArray(System.currentTimeMillis() / 1000) val validDeclaredAddressLen = Set(0, 8, 20) val invalidBytesGen = Gen.listOfN(3, Arbitrary.arbByte.arbitrary).filter { case List(appNameLen, nodeNameLen, declaredAddressLen) => !(appNameLen == appNameBytes.size || nodeNameLen == nodeNameBytes.size || validDeclaredAddressLen.contains(declaredAddressLen)) case _ => false } invalidBytesGen.map { case List(appNameLen, nodeNameLen, declaredAddressLen) => Array(appNameLen) ++ appNameBytes ++ versionBytes ++ Array(nodeNameLen) ++ nodeNameBytes ++ nonceBytes ++ Array(declaredAddressLen) ++ timestampBytes } } "should blacklist a node sends an invalid handshake" in forAll(invalidHandshakeBytes) { bytes: Array[Byte] => val decoder = new SpiedHandshakeDecoder val channel = new EmbeddedChannel(decoder) val buff = Unpooled.buffer buff.writeBytes(bytes) channel.writeInbound(buff) decoder.blockCalls shouldBe >(0) } private class SpiedHandshakeDecoder extends HandshakeDecoder(PeerDatabase.NoOp) { var blockCalls = 0 override protected def block(ctx: ChannelHandlerContext, e: Throwable): Unit = { blockCalls += 1 } } }
Example 18
Source File: MessageCodecSpec.scala From Waves with MIT License | 5 votes |
package com.wavesplatform.network import java.nio.charset.StandardCharsets import com.wavesplatform.TransactionGen import com.wavesplatform.transaction.assets.IssueTransaction import com.wavesplatform.transaction.{ProvenTransaction, Transaction} import io.netty.channel.ChannelHandlerContext import io.netty.channel.embedded.EmbeddedChannel import org.scalamock.scalatest.MockFactory import org.scalatest.{FreeSpec, Matchers} import org.scalatestplus.scalacheck.{ScalaCheckPropertyChecks => PropertyChecks} class MessageCodecSpec extends FreeSpec with Matchers with MockFactory with PropertyChecks with TransactionGen { "should block a sender of invalid messages" in { val codec = new SpiedMessageCodec val ch = new EmbeddedChannel(codec) ch.writeInbound(RawBytes(TransactionSpec.messageCode, "foo".getBytes(StandardCharsets.UTF_8))) ch.readInbound[IssueTransaction]() codec.blockCalls shouldBe 1 } "should not block a sender of valid messages" in forAll(randomTransactionGen) { origTx: ProvenTransaction => val codec = new SpiedMessageCodec val ch = new EmbeddedChannel(codec) ch.writeInbound(RawBytes.fromTransaction(origTx)) val decodedTx = ch.readInbound[Transaction]() decodedTx shouldBe origTx codec.blockCalls shouldBe 0 } private class SpiedMessageCodec extends MessageCodec(PeerDatabase.NoOp) { var blockCalls = 0 override def block(ctx: ChannelHandlerContext, e: Throwable): Unit = { blockCalls += 1 } } }
Example 19
Source File: MessageEncoder.scala From aloha with Apache License 2.0 | 5 votes |
package me.jrwang.aloha.transport.message import java.util import io.netty.channel.{ChannelHandler, ChannelHandlerContext} import io.netty.handler.codec.MessageToMessageEncoder import me.jrwang.aloha.common.Logging @ChannelHandler.Sharable object MessageEncoder extends MessageToMessageEncoder[Message] with Logging { //Be aware that you need to call {@link ReferenceCounted#retain()} on messages //that are just passed through if they are of type {@link ReferenceCounted}. //This is needed as the {@link MessageToMessageEncoder} will call //{@link ReferenceCounted#release()} on encoded messages. override def encode(ctx: ChannelHandlerContext, msg: Message, out: util.List[AnyRef]): Unit = { val messType = msg.`type` //[FrameLength(long)][MessageType][Message][MessageBody(optional)] val headerLength = 8 + messType.encodeLength + msg.encodeLength val frameLength = headerLength + (if(msg.isBodyInFrame) msg.body.readableBytes() else 0) val header = ctx.alloc.heapBuffer(headerLength) header.writeLong(frameLength) messType.encode(header) msg.encode(header) assert(header.writableBytes() == 0) if (msg.isBodyInFrame) { out.add(new MessageWithHeader(header, msg.body, msg.body.readableBytes())) } else { out.add(header) } } }
Example 20
Source File: MessageDecoder.scala From aloha with Apache License 2.0 | 5 votes |
package me.jrwang.aloha.transport.message import java.util import io.netty.buffer.ByteBuf import io.netty.channel.{ChannelHandler, ChannelHandlerContext} import io.netty.handler.codec.MessageToMessageDecoder import me.jrwang.aloha.common.Logging @ChannelHandler.Sharable object MessageDecoder extends MessageToMessageDecoder[ByteBuf] with Logging { //Be aware that you need to call {@link ReferenceCounted#retain()} on messages //that are just passed through if they are of type {@link ReferenceCounted}. //This is needed as the {@link MessageToMessageDecoder} will call //{@link ReferenceCounted#release()} on decoded messages. override def decode(ctx: ChannelHandlerContext, msg: ByteBuf, out: util.List[AnyRef]): Unit = { val msgType = MessageType.decode(msg) val decodedMsg = decode(msgType, msg) require(msgType == decodedMsg.`type`) logTrace(s"Received message ${msgType}: ${decodedMsg}") out.add(decodedMsg) } private def decode(msgType: MessageType, in: ByteBuf) = msgType match { case MessageType.RpcRequest => RpcRequest.decode(in) case MessageType.RpcResponse => RpcResponse.decode(in) case MessageType.RpcFailure => RpcFailure.decode(in) case MessageType.OneWayMessage => OneWayMessage.decode(in) case _ => throw new IllegalArgumentException("Unexpected message type: " + msgType) } }
Example 21
Source File: TransportChannelHandler.scala From aloha with Apache License 2.0 | 5 votes |
package me.jrwang.aloha.transport.server import io.netty.channel.{ChannelHandlerContext, ChannelInboundHandlerAdapter} import me.jrwang.aloha.common.Logging import me.jrwang.aloha.transport.client.{TransportClient, TransportResponseHandler} import me.jrwang.aloha.transport.message.{RequestMessage, ResponseMessage} import me.jrwang.aloha.transport.util.NettyUtils class TransportChannelHandler ( val client: TransportClient, val responseHandler: TransportResponseHandler, val requestHandler: TransportRequestHandler ) extends ChannelInboundHandlerAdapter with Logging { override def channelRead(ctx: ChannelHandlerContext, request: scala.Any): Unit = { request match { case requestMessage: RequestMessage => requestHandler.handle(requestMessage) case responseMessage: ResponseMessage => responseHandler.handle(responseMessage) case _ => ctx.fireChannelRead(request) } } @throws[Exception] override def channelActive(ctx: ChannelHandlerContext): Unit = { try requestHandler.channelActive() catch { case e: Throwable => logError("Exception from request handler while channel is active", e) throw e } try responseHandler.channelActive() catch { case e: Throwable => logError("Exception from response handler while channel is active", e) throw e } super.channelActive(ctx) } @throws[Exception] override def channelInactive(ctx: ChannelHandlerContext): Unit = { try requestHandler.channelInactive() catch { case e: Throwable => logError("Exception from request handler while channel is inactive", e) throw e } try responseHandler.channelInactive() catch { case e: Throwable => logError("Exception from response handler while channel is inactive", e) throw e } super.channelInactive(ctx) } override def exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable): Unit = { logWarning(s"Exception in connection from ${NettyUtils.getRemoteAddress(ctx.channel())}", cause) requestHandler.exceptionCaught(cause) responseHandler.exceptionCaught(cause) ctx.close() } }
Example 22
Source File: UnsharableHandler.scala From netty-in-action-scala with Apache License 2.0 | 5 votes |
package nia.chapter6 import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.ChannelHandlerContext import io.netty.channel.ChannelInboundHandlerAdapter //使用注解@Sharable标注 @Sharable class UnsharableHandler extends ChannelInboundHandlerAdapter { private var count = 0 override def channelRead(ctx: ChannelHandlerContext, msg: Any): Unit = { //将 count 字段的值加 1 count += 1 //记录方法调用,并转发给下一个ChannelHandler System.out.println("inboundBufferUpdated(...) called the " + count + " time") ctx.fireChannelRead(msg) } }
Example 23
Source File: GamePacketEncoderMoP.scala From wowchat with GNU General Public License v3.0 | 5 votes |
package wowchat.game import io.netty.buffer.ByteBuf import io.netty.channel.ChannelHandlerContext import wowchat.common.{ByteUtils, Packet} import scala.collection.mutable.ArrayBuffer class GamePacketEncoderMoP extends GamePacketEncoderCataclysm with GamePacketsMoP18414 { override def encode(ctx: ChannelHandlerContext, msg: Packet, out: ByteBuf): Unit = { val crypt = ctx.channel.attr(CRYPT).get val unencrypted = isUnencryptedPacket(msg.id) val headerSize = 4 val size = msg.byteBuf.writerIndex val array = new ArrayBuffer[Byte](headerSize) val header = if (unencrypted) { array ++= ByteUtils.shortToBytesLE(size + 2) array ++= ByteUtils.shortToBytesLE(msg.id) array.toArray } else { array ++= ByteUtils.intToBytesLE((size << 13) | (msg.id & 0x1FFF)) crypt.encrypt(array.toArray) } logger.debug(f"SEND PACKET: ${msg.id}%04X - ${ByteUtils.toHexString(msg.byteBuf, true, false)}") out.writeBytes(header) out.writeBytes(msg.byteBuf) msg.byteBuf.release } }
Example 24
Source File: GamePacketDecoderCataclysm.scala From wowchat with GNU General Public License v3.0 | 5 votes |
package wowchat.game import java.util.zip.Inflater import io.netty.buffer.{ByteBuf, PooledByteBufAllocator} import io.netty.channel.ChannelHandlerContext class GamePacketDecoderCataclysm extends GamePacketDecoderWotLK with GamePacketsCataclysm15595 { protected val inflater: Inflater = new Inflater override def channelInactive(ctx: ChannelHandlerContext): Unit = { inflater.end() super.channelInactive(ctx) } override def decompress(id: Int, byteBuf: ByteBuf): (Int, ByteBuf) = { if (isCompressed(id)) { val decompressedSize = getDecompressedSize(byteBuf) val compressed = new Array[Byte](byteBuf.readableBytes) byteBuf.readBytes(compressed) byteBuf.release val decompressed = new Array[Byte](decompressedSize) inflater.setInput(compressed) inflater.inflate(decompressed) val ret = PooledByteBufAllocator.DEFAULT.buffer(decompressed.length, decompressed.length) ret.writeBytes(decompressed) (getDecompressedId(id, ret), ret) } else { (id, byteBuf) } } def getDecompressedSize(byteBuf: ByteBuf): Int = { byteBuf.readIntLE } def getDecompressedId(id: Int, buf: ByteBuf): Int = { id ^ COMPRESSED_DATA_MASK } def isCompressed(id: Int): Boolean = { (id & COMPRESSED_DATA_MASK) == COMPRESSED_DATA_MASK } }
Example 25
Source File: GamePacketDecoder.scala From wowchat with GNU General Public License v3.0 | 5 votes |
package wowchat.game import java.util import wowchat.common.{ByteUtils, Packet} import com.typesafe.scalalogging.StrictLogging import io.netty.buffer.ByteBuf import io.netty.channel.ChannelHandlerContext import io.netty.handler.codec.ByteToMessageDecoder class GamePacketDecoder extends ByteToMessageDecoder with GamePackets with StrictLogging { protected val HEADER_LENGTH = 4 private var size = 0 private var id = 0 override def decode(ctx: ChannelHandlerContext, in: ByteBuf, out: util.List[AnyRef]): Unit = { if (in.readableBytes < HEADER_LENGTH) { return } val crypt = ctx.channel.attr(CRYPT).get if (size == 0 && id == 0) { // decrypt if necessary val tuple = if (crypt.isInit) { parseGameHeaderEncrypted(in, crypt) } else { parseGameHeader(in) } id = tuple._1 size = tuple._2 } if (size > in.readableBytes) { return } val byteBuf = in.readBytes(size) // decompress if necessary val (newId, decompressed) = decompress(id, byteBuf) val packet = Packet(newId, decompressed) logger.debug(f"RECV PACKET: $newId%04X - ${ByteUtils.toHexString(decompressed, true, false)}") out.add(packet) size = 0 id = 0 } def parseGameHeader(in: ByteBuf): (Int, Int) = { val size = in.readShort - 2 val id = in.readShortLE (id, size) } def parseGameHeaderEncrypted(in: ByteBuf, crypt: GameHeaderCrypt): (Int, Int) = { val header = new Array[Byte](HEADER_LENGTH) in.readBytes(header) val decrypted = crypt.decrypt(header) val size = ((decrypted(0) & 0xFF) << 8 | decrypted(1) & 0xFF) - 2 val id = (decrypted(3) & 0xFF) << 8 | decrypted(2) & 0xFF (id, size) } // vanilla has no compression. starts in cata/mop def decompress(id: Int, in: ByteBuf): (Int, ByteBuf) = { (id, in) } }
Example 26
Source File: GamePacketEncoder.scala From wowchat with GNU General Public License v3.0 | 5 votes |
package wowchat.game import wowchat.common.{ByteUtils, Packet} import com.typesafe.scalalogging.StrictLogging import io.netty.buffer.ByteBuf import io.netty.channel.ChannelHandlerContext import io.netty.handler.codec.MessageToByteEncoder import scala.collection.mutable.ArrayBuffer class GamePacketEncoder extends MessageToByteEncoder[Packet] with GamePackets with StrictLogging { override def encode(ctx: ChannelHandlerContext, msg: Packet, out: ByteBuf): Unit = { val crypt = ctx.channel.attr(CRYPT).get val unencrypted = isUnencryptedPacket(msg.id) val headerSize = if (unencrypted) 4 else 6 val array = new ArrayBuffer[Byte](headerSize) array ++= ByteUtils.shortToBytes(msg.byteBuf.writerIndex + headerSize - 2) array ++= ByteUtils.shortToBytesLE(msg.id) val header = if (unencrypted) { array.toArray } else { array.append(0, 0) crypt.encrypt(array.toArray) } logger.debug(f"SEND PACKET: ${msg.id}%04X - ${ByteUtils.toHexString(msg.byteBuf, true, false)}") out.writeBytes(header) out.writeBytes(msg.byteBuf) msg.byteBuf.release } protected def isUnencryptedPacket(id: Int): Boolean = { id == CMSG_AUTH_CHALLENGE } }
Example 27
Source File: RealmPacketDecoder.scala From wowchat with GNU General Public License v3.0 | 5 votes |
package wowchat.realm import java.util import wowchat.common.{ByteUtils, Packet, WowChatConfig, WowExpansion} import com.typesafe.scalalogging.StrictLogging import io.netty.buffer.ByteBuf import io.netty.channel.ChannelHandlerContext import io.netty.handler.codec.ByteToMessageDecoder class RealmPacketDecoder extends ByteToMessageDecoder with StrictLogging { private var size = 0 private var id = 0 override def decode(ctx: ChannelHandlerContext, in: ByteBuf, out: util.List[AnyRef]): Unit = { if (in.readableBytes == 0) { return } if (size == 0 && id == 0) { in.markReaderIndex id = in.readByte id match { case RealmPackets.CMD_AUTH_LOGON_CHALLENGE => if (in.readableBytes < 2) { in.resetReaderIndex return } in.markReaderIndex in.skipBytes(1) val result = in.readByte size = if (RealmPackets.AuthResult.isSuccess(result)) { 118 } else { 2 } in.resetReaderIndex case RealmPackets.CMD_AUTH_LOGON_PROOF => if (in.readableBytes < 1) { in.resetReaderIndex return } // size is error dependent in.markReaderIndex val result = in.readByte size = if (RealmPackets.AuthResult.isSuccess(result)) { if (WowChatConfig.getExpansion == WowExpansion.Vanilla) 25 else 31 } else { if (WowChatConfig.getExpansion == WowExpansion.Vanilla) 1 else 3 } in.resetReaderIndex case RealmPackets.CMD_REALM_LIST => if (in.readableBytes < 2) { in.resetReaderIndex return } size = in.readShortLE } } if (size > in.readableBytes) { return } val byteBuf = in.readBytes(size) val packet = Packet(id, byteBuf) logger.debug(f"RECV REALM PACKET: $id%04X - ${ByteUtils.toHexString(byteBuf, true, false)}") out.add(packet) size = 0 id = 0 } }
Example 28
Source File: IdleStateCallback.scala From wowchat with GNU General Public License v3.0 | 5 votes |
package wowchat.common import com.typesafe.scalalogging.StrictLogging import io.netty.channel.{ChannelHandlerContext, ChannelInboundHandlerAdapter} import io.netty.handler.timeout.{IdleState, IdleStateEvent} class IdleStateCallback extends ChannelInboundHandlerAdapter with StrictLogging { override def userEventTriggered(ctx: ChannelHandlerContext, evt: scala.Any): Unit = { evt match { case event: IdleStateEvent => val idler = event.state match { case IdleState.READER_IDLE => "reader" case IdleState.WRITER_IDLE => "writer" case _ => "all" } logger.error(s"Network state for $idler marked as idle!") ctx.close case _ => } super.userEventTriggered(ctx, evt) } }
Example 29
Source File: LogEventHandler.scala From netty-in-action-scala with Apache License 2.0 | 5 votes |
package nia.chapter13 import io.netty.channel.ChannelHandlerContext import io.netty.channel.SimpleChannelInboundHandler //扩展 SimpleChannelInboundHandler 以处理 LogEvent 消息 class LogEventHandler extends SimpleChannelInboundHandler[LogEvent] { @throws[Exception] override def exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable): Unit = { //当异常发生时,打印栈跟踪信息,并关闭对应的 Channel cause.printStackTrace() ctx.close() } @throws[Exception] override def channelRead0(ctx: ChannelHandlerContext, event: LogEvent): Unit = { //打印 LogEvent 的数据 println(event) } }
Example 30
Source File: LogEventEncoder.scala From netty-in-action-scala with Apache License 2.0 | 5 votes |
package nia.chapter13 import io.netty.channel.ChannelHandlerContext import io.netty.channel.socket.DatagramPacket import io.netty.handler.codec.MessageToMessageEncoder import io.netty.util.CharsetUtil import java.net.InetSocketAddress import java.util // LogEventEncoder 创建了即将被发送到指定的 InetSocketAddress 的 DatagramPacket 消息 class LogEventEncoder(remoteAddress: InetSocketAddress) extends MessageToMessageEncoder[LogEvent] { @throws[Exception] override protected def encode( channelHandlerContext: ChannelHandlerContext, logEvent: LogEvent, out: util.List[AnyRef]): Unit = { val file = logEvent.logfile.getBytes(CharsetUtil.UTF_8) val msg = logEvent.msg.getBytes(CharsetUtil.UTF_8) val buf = channelHandlerContext.alloc.buffer(file.length + msg.length + 1) //将文件名写入到 ByteBuf 中 buf.writeBytes(file) //添加一个 SEPARATOR buf.writeByte(LogEvent.SEPARATOR) //将日志消息写入 ByteBuf 中 buf.writeBytes(msg) //将一个拥有数据和目的地地址的新 DatagramPacket 添加到出站的消息列表中 out.add(new DatagramPacket(buf, remoteAddress)) } }
Example 31
Source File: LogEventDecoder.scala From netty-in-action-scala with Apache License 2.0 | 5 votes |
package nia.chapter13 import io.netty.channel.ChannelHandlerContext import io.netty.channel.socket.DatagramPacket import io.netty.handler.codec.MessageToMessageDecoder import io.netty.util.CharsetUtil import java.util class LogEventDecoder extends MessageToMessageDecoder[DatagramPacket] { @throws[Exception] override protected def decode( ctx: ChannelHandlerContext, datagramPacket: DatagramPacket, out: util.List[AnyRef]): Unit = { //获取对 DatagramPacket 中的数据(ByteBuf)的引用 val data = datagramPacket.content //获取该 SEPARATOR 的索引 val idx = data.indexOf(0, data.readableBytes, LogEvent.SEPARATOR) //提取文件名 val filename = data.slice(0, idx).toString(CharsetUtil.UTF_8) //提取日志消息 val logMsg = data.slice(idx + 1, data.readableBytes).toString(CharsetUtil.UTF_8) //构建一个新的 LogEvent 对象,并且将它添加到(已经解码的消息的)列表中 val event = LogEvent(datagramPacket.sender, System.currentTimeMillis, filename, logMsg) out.add(event) } }
Example 32
Source File: FrameHandler.scala From lila-ws with GNU Affero General Public License v3.0 | 5 votes |
package lila.ws package netty import com.typesafe.scalalogging.Logger import io.netty.channel.ChannelHandlerContext import io.netty.channel.SimpleChannelInboundHandler import io.netty.handler.codec.http.websocketx.TextWebSocketFrame import io.netty.handler.codec.http.websocketx.WebSocketFrame import scala.concurrent.ExecutionContext import ipc.ClientOut final private class FrameHandler(implicit ec: ExecutionContext) extends SimpleChannelInboundHandler[WebSocketFrame] { import FrameHandler._ import ProtocolHandler.key override protected def channelRead0( ctx: ChannelHandlerContext, anyFrame: WebSocketFrame ) = anyFrame match { case frame: TextWebSocketFrame => val txt = frame.text if (txt.nonEmpty) { val limiter = ctx.channel.attr(key.limit).get if (limiter == null || limiter(txt)) ClientOut parse txt foreach { case ClientOut.Unexpected(msg) => Monitor.clientOutUnexpected.increment() logger.info(s"Unexpected $msg") case ClientOut.WrongHole => Monitor.clientOutWrongHole.increment() case out => Option(ctx.channel.attr(key.client).get) match { case Some(clientFu) => clientFu.value match { case Some(client) => client foreach (_ ! out) case None => clientFu foreach (_ ! out) } case None => logger.warn(s"No client actor to receive $out") } } } case frame => logger.info("unsupported frame type: " + frame.getClass().getName()) } } private object FrameHandler { private val logger = Logger(getClass) }
Example 33
Source File: WriteHandler.scala From netty-in-action-scala with Apache License 2.0 | 5 votes |
package nia.chapter6 import io.netty.channel.ChannelHandlerAdapter import io.netty.channel.ChannelHandlerContext class WriteHandler extends ChannelHandlerAdapter { private var ctx: ChannelHandlerContext = _ override def handlerAdded(ctx: ChannelHandlerContext): Unit = { //存储到 ChannelHandlerContext的引用以供稍后使用 this.ctx = ctx } def send(msg: String): Unit = { //使用之前存储的到 ChannelHandlerContext的引用来发送消息 ctx.writeAndFlush(msg) } }
Example 34
Source File: EchoClientHandler.scala From netty-in-action-scala with Apache License 2.0 | 5 votes |
package nia.chapter2.echoclient import io.netty.buffer.{ ByteBuf, Unpooled } import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.{ ChannelHandlerContext, SimpleChannelInboundHandler } import io.netty.util.CharsetUtil @Sharable //标记该类的实例可以被多个 Channel 共享 class EchoClientHandler extends SimpleChannelInboundHandler[ByteBuf] { override def channelActive(ctx: ChannelHandlerContext): Unit = { //当被通知 Channel是活跃的时候,发送一条消息 ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks!", CharsetUtil.UTF_8)) } override def channelRead0(ctx: ChannelHandlerContext, in: ByteBuf): Unit = { //记录已接收消息的转储 System.out.println("Client received: " + in.toString(CharsetUtil.UTF_8)) } override def exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable): Unit = { //在发生异常时,记录错误并关闭Channel cause.printStackTrace() ctx.close() } }
Example 35
Source File: EchoServerHandler.scala From netty-in-action-scala with Apache License 2.0 | 5 votes |
package nia.chapter2.echoserver import io.netty.buffer.{ ByteBuf, Unpooled } import io.netty.channel.ChannelHandler.Sharable import io.netty.channel.{ ChannelFutureListener, ChannelHandlerContext, ChannelInboundHandlerAdapter } import io.netty.util.CharsetUtil @Sharable class EchoServerHandler extends ChannelInboundHandlerAdapter { override def channelRead(ctx: ChannelHandlerContext, msg: Any): Unit = { val in = msg.asInstanceOf[ByteBuf] //将消息记录到控制台 System.out.println("Server received: " + in.toString(CharsetUtil.UTF_8)) //将接收到的消息写给发送者,而不冲刷出站消息 ctx.write(in) } @throws[Exception] override def channelReadComplete(ctx: ChannelHandlerContext): Unit = { //将未决消息冲刷到远程节点,并且关闭该 Channel ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE) } override def exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable): Unit = { //打印异常栈跟踪 cause.printStackTrace() //关闭该Channel ctx.close() } }
Example 36
Source File: InvalidBootstrapClient.scala From netty-in-action-scala with Apache License 2.0 | 5 votes |
package nia.chapter8 import io.netty.bootstrap.Bootstrap import io.netty.buffer.ByteBuf import io.netty.channel.ChannelHandlerContext import io.netty.channel.SimpleChannelInboundHandler import io.netty.channel.nio.NioEventLoopGroup import io.netty.channel.socket.oio.OioSocketChannel import java.net.InetSocketAddress def bootstrap(): Unit = { val group = new NioEventLoopGroup //创建一个新的 Bootstrap 类的实例,以创建新的客户端Channel val bootstrap = new Bootstrap //指定一个适用于 NIO 的 EventLoopGroup 实现 bootstrap.group(group) //指定一个适用于 OIO 的 Channel 实现类 .channel(classOf[OioSocketChannel]) //设置一个用于处理 Channel的 I/O 事件和数据的 ChannelInboundHandler .handler { new SimpleChannelInboundHandler[ByteBuf]() { @throws[Exception] override protected def channelRead0(channelHandlerContext: ChannelHandlerContext, byteBuf: ByteBuf): Unit = { println("Received data") } } } //尝试连接到远程节点 val future = bootstrap.connect(new InetSocketAddress("www.manning.com", 80)) future.syncUninterruptibly } }
Example 37
Source File: BootstrapSharingEventLoopGroup.scala From netty-in-action-scala with Apache License 2.0 | 5 votes |
package nia.chapter8 import io.netty.bootstrap.Bootstrap import io.netty.bootstrap.ServerBootstrap import io.netty.buffer.ByteBuf import io.netty.channel.ChannelFuture import io.netty.channel.ChannelFutureListener import io.netty.channel.ChannelHandlerContext import io.netty.channel.SimpleChannelInboundHandler import io.netty.channel.nio.NioEventLoopGroup import io.netty.channel.socket.nio.NioServerSocketChannel import io.netty.channel.socket.nio.NioSocketChannel import java.net.InetSocketAddress def bootstrap(): Unit = { //创建 ServerBootstrap 以创建 ServerSocketChannel,并绑定它 val bootstrap = new ServerBootstrap //设置 EventLoopGroup,其将提供用以处理 Channel 事件的 EventLoop bootstrap.group(new NioEventLoopGroup, new NioEventLoopGroup) //指定要使用的 Channel 实现 .channel(classOf[NioServerSocketChannel]) //设置用于处理已被接受的子 Channel 的 I/O 和数据的 ChannelInboundHandler .childHandler { new SimpleChannelInboundHandler[ByteBuf]() { private[chapter8] var connectFuture: ChannelFuture = _ @throws[Exception] override def channelActive(ctx: ChannelHandlerContext): Unit = { //创建一个 Bootstrap 类的实例以连接到远程主机 val bootstrap = new Bootstrap //指定 Channel 的实现 bootstrap.channel(classOf[NioSocketChannel]) .handler(new SimpleChannelInboundHandler[ByteBuf]() { @throws[Exception] override protected def channelRead0( ctx: ChannelHandlerContext, in: ByteBuf): Unit = { println("Received data") } }) //使用与分配给已被接受的子Channel相同的EventLoop bootstrap.group(ctx.channel.eventLoop) //连接到远程节点 connectFuture = bootstrap.connect(new InetSocketAddress("www.manning.com", 80)) } @throws[Exception] override protected def channelRead0( channelHandlerContext: ChannelHandlerContext, byteBuf: ByteBuf): Unit = { if (connectFuture.isDone) { //当连接完成时,执行一些数据操作(如代理) // do something with the data } } } } //通过配置好的 ServerBootstrap 绑定该 ServerSocketChannel val future = bootstrap.bind(new InetSocketAddress(8080)) future.addListener(new ChannelFutureListener() { @throws[Exception] override def operationComplete(channelFuture: ChannelFuture): Unit = { if (channelFuture.isSuccess) System.out.println("Server bound") else { System.err.println("Bind attempt failed") channelFuture.cause.printStackTrace() } } }) } }
Example 38
Source File: BootstrapServer.scala From netty-in-action-scala with Apache License 2.0 | 5 votes |
package nia.chapter8 import io.netty.bootstrap.ServerBootstrap import io.netty.buffer.ByteBuf import io.netty.channel.ChannelFuture import io.netty.channel.ChannelFutureListener import io.netty.channel.ChannelHandlerContext import io.netty.channel.SimpleChannelInboundHandler import io.netty.channel.nio.NioEventLoopGroup import io.netty.channel.socket.nio.NioServerSocketChannel import java.net.InetSocketAddress def bootstrap(): Unit = { val group = new NioEventLoopGroup //创建 Server Bootstrap val bootstrap = new ServerBootstrap //设置 EventLoopGroup,其提供了用于处理 Channel 事件的EventLoop bootstrap.group(group) //指定要使用的 Channel 实现 .channel(classOf[NioServerSocketChannel]) //设置用于处理已被接受的子 Channel 的I/O及数据的 ChannelInboundHandler .childHandler { new SimpleChannelInboundHandler[ByteBuf]() { @throws[Exception] override protected def channelRead0(channelHandlerContext: ChannelHandlerContext, byteBuf: ByteBuf): Unit = { System.out.println("Received data") } } } //通过配置好的 ServerBootstrap 的实例绑定该 Channel val future = bootstrap.bind(new InetSocketAddress(8080)) future.addListener(new ChannelFutureListener() { @throws[Exception] override def operationComplete(channelFuture: ChannelFuture): Unit = { if (channelFuture.isSuccess) System.out.println("Server bound") else { System.err.println("Bind attempt failed") channelFuture.cause.printStackTrace() } } }) } }
Example 39
Source File: BootstrapDatagramChannel.scala From netty-in-action-scala with Apache License 2.0 | 5 votes |
package nia.chapter8 import io.netty.bootstrap.Bootstrap import io.netty.channel.ChannelFuture import io.netty.channel.ChannelFutureListener import io.netty.channel.ChannelHandlerContext import io.netty.channel.SimpleChannelInboundHandler import io.netty.channel.oio.OioEventLoopGroup import io.netty.channel.socket.DatagramPacket import io.netty.channel.socket.oio.OioDatagramChannel import java.net.InetSocketAddress def bootstrap(): Unit = { //创建一个 Bootstrap 的实例以创建和绑定新的数据报 Channel val bootstrap = new Bootstrap //设置 EventLoopGroup,其提供了用以处理 Channel 事件的 EventLoop bootstrap.group(new OioEventLoopGroup) //指定 Channel 的实现 .channel(classOf[OioDatagramChannel]) .handler(new SimpleChannelInboundHandler[DatagramPacket]() { @throws[Exception] override def channelRead0(ctx: ChannelHandlerContext, msg: DatagramPacket): Unit = { // Do something with the packet } }) //调用 bind() 方法,因为该协议是无连接的 val future = bootstrap.bind(new InetSocketAddress(0)) future.addListener(new ChannelFutureListener() { @throws[Exception] override def operationComplete(channelFuture: ChannelFuture): Unit = { if (channelFuture.isSuccess) println("Channel bound") else { System.err.println("Bind attempt failed") channelFuture.cause.printStackTrace() } } }) } }
Example 40
Source File: BootstrapClientWithOptionsAndAttrs.scala From netty-in-action-scala with Apache License 2.0 | 5 votes |
package nia.chapter8 import io.netty.bootstrap.Bootstrap import io.netty.buffer.ByteBuf import io.netty.channel.ChannelHandlerContext import io.netty.channel.ChannelOption import io.netty.channel.SimpleChannelInboundHandler import io.netty.channel.nio.NioEventLoopGroup import io.netty.channel.socket.nio.NioSocketChannel import io.netty.util.AttributeKey import java.net.InetSocketAddress import java.lang.{ Boolean ⇒ JBoolean } def bootstrap(): Unit = { //创建一个 AttributeKey 以标识该属性 val id: AttributeKey[Integer] = AttributeKey.newInstance("ID") //创建一个 Bootstrap 类的实例以创建客户端 Channel 并连接它们 val bootstrap = new Bootstrap //设置 EventLoopGroup,其提供了用以处理 Channel 事件的 EventLoop bootstrap.group(new NioEventLoopGroup) .channel(classOf[NioSocketChannel]) .handler(new SimpleChannelInboundHandler[ByteBuf]() { @throws[Exception] override def channelRegistered(ctx: ChannelHandlerContext): Unit = { //使用 AttributeKey 检索属性以及它的值 val idValue = ctx.channel.attr(id).get // do something with the idValue } @throws[Exception] override protected def channelRead0(channelHandlerContext: ChannelHandlerContext, byteBuf: ByteBuf): Unit = { System.out.println("Received data") } }) //设置 ChannelOption,其将在 connect()或者bind()方法被调用时被设置到已经创建的 Channel 上 bootstrap .option[JBoolean](ChannelOption.SO_KEEPALIVE, true) .option[Integer](ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) //存储该 id 属性 bootstrap.attr[Integer](id, 123456) //使用配置好的 Bootstrap 实例连接到远程主机 val future = bootstrap.connect(new InetSocketAddress("www.manning.com", 80)) future.syncUninterruptibly } }
Example 41
Source File: MethodNotFoundHandler.scala From grpcgateway with MIT License | 5 votes |
package grpcgateway.handlers import io.netty.channel.{ChannelFutureListener, ChannelHandlerContext, ChannelInboundHandlerAdapter} import io.netty.handler.codec.http.{FullHttpRequest, HttpResponseStatus} class MethodNotFoundHandler extends ChannelInboundHandlerAdapter { override def channelRead(ctx: ChannelHandlerContext, msg: scala.Any): Unit = { msg match { case req: FullHttpRequest => ctx.writeAndFlush { buildFullHttpResponse( requestMsg = req, responseBody = "Method isn't supported", responseStatus = HttpResponseStatus.BAD_REQUEST, responseContentType = "application/text" ) }.addListener(ChannelFutureListener.CLOSE) case _ => super.channelRead(ctx, msg) } } }