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 ...
随机推荐
- C Primer Plus(第五版)10
第 10 章 数组和指针 在本章中你将学习下列内容: · 关键字: static (静态) · 运算符: & * (一元) · 创建与初始化数组的方法. · 指针(基于已学的基础知识)及指针和 ...
- sql server远程访问Oracle数据库
在sql server上新建了连接服务器后 在指定的链接服务器上执行指定的传递查询. 该服务器是 OLE DB 数据源. OPENQUERY 可以在查询的 FROM 子句中引用,就好象它是一个表名. ...
- Unity小厨房之-----背后视角摄像机
相信每一个接触过Unity的人,应该都认识Unity引擎自带的那个水管工,也一定知道那个小人模型上挂着3个脚本控制着小人的一切,今天我就来说一下关于Unity背后视角摄像机的实现,当然方法并不唯一,这 ...
- blocksit
<!DOCTYPE html> <html> <head> <title>Sc.Chinaz.Com</title> & ...
- OC基础(21)
Foundation框架介绍 NSString基本概念 字符串读写 字符串比较 字符串搜索 字符串截取 字符串替换 字符串与路径 字符串与基本数据类型转换 *:first-child { margin ...
- 《Code Complete》ch.18 表驱动法
是什么 一种scheme,用表来做信息存取,代替逻辑语句(if/else) 为什么 简化逻辑语句,避免大量嵌套的 if/else 或者 switch/case 怎么用 三种访问表的方式 直接访问:将源 ...
- jmeter随笔(11)--上传文件接口出错
点击标题下「飞测」可快速关注 坚持的是分享,搬运的是知识,图的是大家的进步,没有收费的培训,没有虚度的吹水,喜欢就关注.转发(免费帮助更多伙伴)等来交流,想了解的知识请留言,给你带来更多价值,是我们期 ...
- PL/0与Pascal-S编译器程序详细注释
学校编译课的作业之一,要求阅读两个较为简单的编译器的代码并做注释, 个人感觉是一次挺有意义的锻炼, 将自己的心得分享出来与一同在进步的同学们分享. 今后有时间再做进一步的更新和总结,其中可能有不少错误 ...
- vss error reading from file 解决方法
vss error reading from file 解决方法 1 若服务器中存在 vss/data/backup目录,请将该目录删掉2 运行cmd cd.. cd C:\Program Files ...
- 开机自启动redis
修改redis.conf,打开后台运行选项: # By default Redis does not run as a daemon. Use 'yes' if you need it. # Note ...