scala实现Netty通信
在学习spark源码的时候看到spark在1.6之后底层的通信框架变成了akka和netty两种方式,默认的是用netty根据源码的思路用scala写了一个Demo级别的netty通信
package com.spark.netty
import io.netty.bootstrap.ServerBootstrap
import io.netty.channel.ChannelInitializer
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.SocketChannel
import io.netty.channel.socket.nio.NioServerSocketChannel
import io.netty.handler.codec.serialization.{ClassResolvers, ClassResolver, ObjectDecoder, ObjectEncoder} /**
* Created by root on 2016/11/18.
*/
class NettyServer {
def bind(host: String, port: Int): Unit = {
//配置服务端线程池组
//用于服务器接收客户端连接
val bossGroup = new NioEventLoopGroup()
//用户进行SocketChannel的网络读写
val workerGroup = new NioEventLoopGroup() try {
//是Netty用户启动NIO服务端的辅助启动类,降低服务端的开发复杂度
val bootstrap = new ServerBootstrap()
//将两个NIO线程组作为参数传入到ServerBootstrap
bootstrap.group(bossGroup, workerGroup)
//创建NioServerSocketChannel
.channel(classOf[NioServerSocketChannel])
//绑定I/O事件处理类
.childHandler(new ChannelInitializer[SocketChannel] {
override def initChannel(ch: SocketChannel): Unit = {
ch.pipeline().addLast(
// new ObjectEncoder,
// new ObjectDecoder(ClassResolvers.cacheDisabled(getClass.getClassLoader)),
new ServerHandler
)
}
})
//绑定端口,调用sync方法等待绑定操作完成
val channelFuture = bootstrap.bind(host, port).sync()
//等待服务关闭
channelFuture.channel().closeFuture().sync()
} finally {
//优雅的退出,释放线程池资源
bossGroup.shutdownGracefully()
workerGroup.shutdownGracefully()
}
}
} object NettyServer {
def main(args: Array[String]) {
val host = args()
val port = args().toInt
val server = new NettyServer
server.bind(host, port)
}
}
package com.spark.netty import io.netty.bootstrap.Bootstrap
import io.netty.channel.ChannelInitializer
import io.netty.channel.nio.NioEventLoopGroup
import io.netty.channel.socket.SocketChannel
import io.netty.channel.socket.nio.{NioSocketChannel, NioServerSocketChannel}
import io.netty.handler.codec.serialization.{ClassResolvers, ObjectDecoder, ObjectEncoder} /**
* Created by root on 2016/11/18.
*/ class NettyClient {
def connect(host: String, port: Int): Unit = {
//创建客户端NIO线程组
val eventGroup = new NioEventLoopGroup
//创建客户端辅助启动类
val bootstrap = new Bootstrap
try {
//将NIO线程组传入到Bootstrap
bootstrap.group(eventGroup)
//创建NioSocketChannel
.channel(classOf[NioSocketChannel])
//绑定I/O事件处理类
.handler(new ChannelInitializer[SocketChannel] {
override def initChannel(ch: SocketChannel): Unit = {
ch.pipeline().addLast(
// new ObjectEncoder,
// new ObjectDecoder(ClassResolvers.cacheDisabled(getClass.getClassLoader)),
new ClientHandler
)
}
})
//发起异步连接操作
val channelFuture = bootstrap.connect(host, port).sync()
//等待服务关闭
channelFuture.channel().closeFuture().sync()
} finally {
//优雅的退出,释放线程池资源
eventGroup.shutdownGracefully()
}
}
} object NettyClient {
def main(args: Array[String]) {
val host = args()
val port = args().toInt
val client = new NettyClient
client.connect(host, port)
}
}
package com.spark.netty
import io.netty.buffer.{Unpooled, ByteBuf}
import io.netty.channel.{ChannelHandlerContext, ChannelInboundHandlerAdapter}
/**
* Created by root on 2016/11/18.
*/
class ServerHandler extends ChannelInboundHandlerAdapter {
/**
* 有客户端建立连接后调用
*/
override def channelActive(ctx: ChannelHandlerContext): Unit = {
println("channelActive invoked")
}
/**
* 接受客户端发送来的消息
*/
override def channelRead(ctx: ChannelHandlerContext, msg: scala.Any): Unit = {
println("channelRead invoked")
val byteBuf = msg.asInstanceOf[ByteBuf]
val bytes = new Array[Byte](byteBuf.readableBytes())
byteBuf.readBytes(bytes)
val message = new String(bytes, "UTF-8")
println(message)
val back = "good boy!"
val resp = Unpooled.copiedBuffer(back.getBytes("UTF-8"))
println(msg)
ctx.write(resp)
}
/**
* 将消息对列中的数据写入到SocketChanne并发送给对方
*/
override def channelReadComplete(ctx: ChannelHandlerContext): Unit = {
println("channekReadComplete invoked")
ctx.flush()
}
}
package com.spark.netty
import io.netty.buffer.{ByteBuf, Unpooled}
import io.netty.channel.{ChannelInboundHandlerAdapter, ChannelHandlerContext, ChannelHandlerAdapter}
/**
* Created by root on 2016/11/18.
*/
class ClientHandler extends ChannelInboundHandlerAdapter {
override def channelActive(ctx: ChannelHandlerContext): Unit = {
println("channelActive")
val content = "hello server"
ctx.writeAndFlush(Unpooled.copiedBuffer(content.getBytes("UTF-8")))
//发送case class 不在发送字符串了,封装一个字符串
// ctx.writeAndFlush(RegisterMsg("hello server"))
}
override def channelRead(ctx: ChannelHandlerContext, msg: scala.Any): Unit = {
println("channelRead")
val byteBuf = msg.asInstanceOf[ByteBuf]
val bytes = new Array[Byte](byteBuf.readableBytes())
byteBuf.readBytes(bytes)
val message = new String(bytes, "UTF-8")
println(message)
}
override def channelReadComplete(ctx: ChannelHandlerContext): Unit = {
println("channeReadComplete")
ctx.flush()
}
//发送异常时关闭
override def exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable): Unit = {
println("exceptionCaught")
ctx.close()
}
}
package com.spark.netty /**
* Created by root on 2016/11/18.
*/
case class RegisterMsg(content: String) extends Serializable
先启动NettyServer,然后在启动NettyClient.打印结果


scala实现Netty通信的更多相关文章
- Spark1.6之后为何使用Netty通信框架替代Akka
解决方案: 一直以来,基于Akka实现的RPC通信框架是Spark引以为豪的主要特性,也是与Hadoop等分布式计算框架对比过程中一大亮点. 但是时代和技术都在演化,从Spark1.3.1版本开始,为 ...
- Spark Netty 通信框架解析
1.RpcEndpoint: RPC端点 Spark针对每个节点(Client.Master.Worker)都称之为一个RpcEndpoint,且都实现RpcEndpoint接口,内部根据不同端点的需 ...
- 基于Java Mina 和Netty 通信框架的JT/T809转发服务器设计
Apache MINA 是 Apache 组织的一个开源项目,为开发高性能和高可用性的网络应用程序提供了非常便利的框架. 也是Java开发者的一个福利(.NET目前还没有类似封装的这么好的基础sock ...
- netty通信
学习netty之前,要先了解操作系统中的IO.零拷贝(已经附上链接了) 一.netty的简单介绍 Netty 是由 JBOSS 提供的一个 Java 开源框架,现为 Github 上的独立项目. Ne ...
- scala的tcp通信
client: object ActorClient extends App { import actors.Actor, actors.remote.Node, actors.remote.Remo ...
- Netty通信原理
Netty是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端,它极大的简化了TCP和UDP套接字服务器等网络编程. BIO(Blocking IO):每一个请求,一个S ...
- Netty通信网络参数配置
Netty服务端/客户端网络通信过程中常用的参数: Name Associated setter method "writeBufferHighWaterMark" 默认64 * ...
- Netty 学习笔记(1)通信原理
前言 本文主要从 select 和 epoll 系统调用入手,来打开 Netty 的大门,从认识 Netty 的基础原理 —— I/O 多路复用模型开始. Netty 的通信原理 Netty 底层 ...
- 实现Netty服务器与CocosCreate通信
尽量采用无锁化Netty通信处理棋牌房间逻辑 一,棋牌类服务器的特点 1,棋牌类不分区不分服 一般来说,棋牌游戏都是不分区不分服的.所以棋牌类服务器要满足随着用户量的增加而扩展的需要,所以需要设计Ga ...
随机推荐
- (easy)LeetCode 226.Invert Binary Tree
Invert a binary tree. 4 / \ 2 7 / \ / \ 1 3 6 9 to 4 / \ 7 2 / \ / \ 9 6 3 1 Trivia:This problem was ...
- 【转】开源性能测试工具 - Apache ab 介绍
版权声明:本文可以被转载,但是在未经本人许可前,不得用于任何商业用途或其他以盈利为目的的用途.本人保留对本文的一切权利.如需转载,请在转载是保留此版权声明,并保证本文的完整性.也请转贴者理解创作的辛劳 ...
- HDU 4118 Holiday's Accommodation
Holiday's Accommodation Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 200000/200000 K (Jav ...
- 迁移到 Express 4.x
原文地址: http://expressjs.com/migrating-4.html 概览 从 Express 3 到Express 4 是一个巨大的变化,这意味着现存的 Express 3 应用在 ...
- 关于lambda表达式在javascript中的使用
了解过js函数的同学应该都知道js的函数有很多种创建方式. 如: function fun(){}: var fun=function(){}: 但最近的学习中发现了lambda表达式型的创建js的匿 ...
- vss error reading from file 解决方法
vss error reading from file 解决方法 1 若服务器中存在 vss/data/backup目录,请将该目录删掉2 运行cmd cd.. cd C:\Program Files ...
- C#中的委托,匿名方法和Lambda表达式
简介 在.NET中,委托,匿名方法和Lambda表达式很容易发生混淆.我想下面的代码能证实这点.下面哪一个First会被编译?哪一个会返回我们需要的结果?即Customer.ID=.答案是6个Firs ...
- linux下的mysql乱码问题
1,承接上一随笔,因为我用的是rmp的两种反式. rpm -ivh MySQL-server-4.0.14-0.i386.rpm rpm -ivh MySQL-client-4.0.14-0.i386 ...
- javascript代码复用模式
代码复用有一个著名的原则,是GoF提出的:优先使用对象组合,而不是类继承.在javascript中,并没有类的概念,所以代码的复用,也并不局限于类式继承.javascript中创建对象的方法很多,有构 ...
- jenkins smtp设置调试