在学习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通信的更多相关文章

  1. Spark1.6之后为何使用Netty通信框架替代Akka

    解决方案: 一直以来,基于Akka实现的RPC通信框架是Spark引以为豪的主要特性,也是与Hadoop等分布式计算框架对比过程中一大亮点. 但是时代和技术都在演化,从Spark1.3.1版本开始,为 ...

  2. Spark Netty 通信框架解析

    1.RpcEndpoint: RPC端点 Spark针对每个节点(Client.Master.Worker)都称之为一个RpcEndpoint,且都实现RpcEndpoint接口,内部根据不同端点的需 ...

  3. 基于Java Mina 和Netty 通信框架的JT/T809转发服务器设计

    Apache MINA 是 Apache 组织的一个开源项目,为开发高性能和高可用性的网络应用程序提供了非常便利的框架. 也是Java开发者的一个福利(.NET目前还没有类似封装的这么好的基础sock ...

  4. netty通信

    学习netty之前,要先了解操作系统中的IO.零拷贝(已经附上链接了) 一.netty的简单介绍 Netty 是由 JBOSS 提供的一个 Java 开源框架,现为 Github 上的独立项目. Ne ...

  5. scala的tcp通信

    client: object ActorClient extends App { import actors.Actor, actors.remote.Node, actors.remote.Remo ...

  6. Netty通信原理

    Netty是一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端,它极大的简化了TCP和UDP套接字服务器等网络编程. BIO(Blocking IO):每一个请求,一个S ...

  7. Netty通信网络参数配置

    Netty服务端/客户端网络通信过程中常用的参数: Name Associated setter method "writeBufferHighWaterMark" 默认64 * ...

  8. Netty 学习笔记(1)通信原理

    前言 本文主要从 select 和 epoll 系统调用入手,来打开 Netty 的大门,从认识 Netty 的基础原理 —— I/O 多路复用模型开始.   Netty 的通信原理 Netty 底层 ...

  9. 实现Netty服务器与CocosCreate通信

    尽量采用无锁化Netty通信处理棋牌房间逻辑 一,棋牌类服务器的特点 1,棋牌类不分区不分服 一般来说,棋牌游戏都是不分区不分服的.所以棋牌类服务器要满足随着用户量的增加而扩展的需要,所以需要设计Ga ...

随机推荐

  1. DBCP数据库连接池

    在用JDBC连接数据库的时候,需要创建对数据库的连接,这样才能执行后续的操作.然而,这样做有两个问题: 数据库允许的连接个数有限 创建连接的过程需要消耗内存和时间 所以,JDBC引入了连接池的概念.也 ...

  2. [SQL] 要查询9 月份的数据中的任意时间段,可能是一个月的,也可能是1日到15日的

    SELECT * FROM [表名] WHERE datediff(month,[列名],

  3. AndroidManifest.xml 屏幕上下反转

    通常我们的应用只会设计成横屏或者竖屏,锁定横屏或竖屏的方法是在AndroidManifest.xml 文件中设定属性android:screenOrientation为"landscape& ...

  4. 项目管理: Maven 让事情变得简单

    http://maven.apache.org/,  Maven其实就是为java实现的一个构建工具.他比Ant更高端. 目前,绝大多数开发人员都把 Ant 当作 Java 编程项目的标准构建工具.遗 ...

  5. 为什么需要auto_ptr_ref

    这几天开始拜读侯捷先生和孟岩先生的译作<C++标准程序库:自修教程与参考手册> .两位先生确实译功上乘,读得很顺.但是读到P55页关于auto_ptr_ref的讨论,却百思不得其解:为什么 ...

  6. SQLServer 索引以及视图

    业务 主键: 索引: 锁: ========================================= 一个页分为 页头 页体--存储行 页尾 页是有固定大小的,但是数据不一定存满,有可能产生 ...

  7. php array函数实例应用

    array_diff_key() array_diff_assoc() array_count_values() array_combine() array_column() array_chunk( ...

  8. [转]iOS技巧之获取本机通讯录中的内容,解析通讯录源代码

    一.在工程中添加AddressBook.framework和AddressBookUI.framework 二.获取通讯录 1.在infterface中定义数组并在init方法中初始化 ? 1 2 3 ...

  9. vc 判断哪个按键 被按下 消息 按键 状态

    测试Numlock 是否是亮的 环境控制台程序: #include "stdafx.h" #include <stdio.h> #include <conio.h ...

  10. VC 获 取 当前程序运行路径的几种方法

    1.使用APi函数GetModuleFileName char path[MAX_PATH]; GetModuleFileName(NULL, path, MAX_PATH);        //获取 ...