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 ...
随机推荐
- Django 之 下载文件
法I: views.py #encoding:utf-8 import os from django.core.servers.basehttp import FileWrapper from dja ...
- golang.org/x/mobile/exp/gl/glutil/glimage.go 源码分析
看这篇之前,建议先看之前几篇,这几篇是基础. Go Mobile 例子 basic 源码分析 http://www.cnblogs.com/ghj1976/p/5183199.html OpenGL ...
- [datatable]两个DataTable 连接
using System; using System.Collections.Generic; using System.Text; using System.Data; namespace Cons ...
- elasticsearch开启脚本及使用
开启script: Scripting settingsedit The script.disable_dynamic node setting has been replaced by fine-g ...
- 共享池之八:软解析、硬解析、软软解析 详解一条SQL在library cache中解析涉及的锁
先来张大图: 结合上图来说明一下解析的各个步骤涉及的锁. 软解析.硬解析.软软解析区别的简单说明: 为了将用户写的sql文本转化为oracle认识的且可执行的语句,这个过程就叫做解析过程. 解析分为硬 ...
- Xcode引入外界文件时选Create groups 或 Create folder references的区别
一.使用Create groups 我们在项目中可以手动添加一个groups(右键点击选择New Group),但是手动添加的groups实际上并不会存在于项目的目录中,被添加进groups中的文件仍 ...
- NSUrl 的常见用法
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com/s?tn=baiduhome_pg&bs=NSRUL&f=8 ...
- MFC创建非模态对话框并修改CStatic文字
//由IDD_STATUS_DIALOG创建一个对话框CDialog* pCheckNetStatusDlg = new CDialog(); pCheckNetStatusDlg->Creat ...
- 剑指Offer:面试题4——替换空格(java实现)
问题描述:请实现一个函数,把字符串中的每个空格替换成"%20". 例如: 输入:"We are happy." 输出:"We%20are%20happ ...
- PostMan入门使用教程
最近需要测试产品中的REST API,无意中发现了PostMan这个chrome插件,把玩了一下,发现postman秉承了一贯以来google工具强大,易用的特质.独乐乐不如众乐乐,特此共享出来给大伙 ...