Netty實現長連線簡單例子
Netty實現長連線的簡單例子
服務端
NettyServerBootstrap提供長連線服務
public class NettyServerBootstrap { private static final Log log = LogFactory.getLog(NettyServerBootstrap.class); private Integer port; private SocketChannel socketChannel; public NettyServerBootstrap(Integer port) throws Exception { this.port = port; bind(port); } public Integer getPort() { return port; } public void setPort(Integer port) { this.port = port; } public SocketChannel getSocketChannel() { return socketChannel; } public void setSocketChannel(SocketChannel socketChannel) { this.socketChannel = socketChannel; } private void bind(int serverPort) throws Exception { // 連線處理group EventLoopGroup boss = new NioEventLoopGroup(); // 事件處理group EventLoopGroup worker = new NioEventLoopGroup(); ServerBootstrap bootstrap = new ServerBootstrap(); // 繫結處理group bootstrap.group(boss, worker); bootstrap.channel(NioServerSocketChannel.class); // 保持連線數 bootstrap.option(ChannelOption.SO_BACKLOG, 1024 * 1024); // 有資料立即傳送 bootstrap.option(ChannelOption.TCP_NODELAY, true); // 保持連線 bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true); // 處理新連線 bootstrap.childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel sc) throws Exception { // 增加任務處理 ChannelPipeline p = sc.pipeline(); p.addLast(new MessageDecoder(), new MessageEncoder(), new NettyServerHandler()); } }); ChannelFuture f = bootstrap.bind(serverPort).sync(); if (f.isSuccess()) { log.info("long connection started success"); } else { log.error("long connection started fail"); } } }
啟動服務,監聽9999埠
public static void main(String[] args) {
try {
new NettyServerBootstrap(9999);
} catch (Exception e) {
e.printStackTrace();
}
}
定義客戶端服務端通訊協議,一下是一個簡單的通訊協議
協議分為header和body兩部分,都是用網路位元組序(BIG ENDIAN) header{ magic 32bit; //校驗用固定值0x0CAFFEE0 version 8bit; //版本號 type 8bit; //型別,請求或者響應 seq 32bit; //序號標記一對請求響應 length 32bit; //body長度 } body{ } |
根據通訊協議,編寫解碼器和編碼器
解碼器MessageDecoder
public class MessageDecoder extends ByteToMessageDecoder { private static final int MAGIC_NUMBER = 0x0CAFFEE0; public MessageDecoder() { } @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { if (in.readableBytes() < 14) { return; } // 標記開始讀取位置 in.markReaderIndex(); int magic_number = in.readInt(); if (MAGIC_NUMBER != magic_number) { ctx.close(); return; } @SuppressWarnings("unused") byte version = in.readByte(); byte type = in.readByte(); int squence = in.readInt(); int length = in.readInt(); if (length < 0) { ctx.close(); return; } if (in.readableBytes() < length) { // 重置到開始讀取位置 in.resetReaderIndex(); return; } byte[] body = new byte[length]; in.readBytes(body); RequestInfoVO req = new RequestInfoVO(); req.setBody(new String(body, "utf-8")); req.setType(type); req.setSequence(squence); out.add(req); } }
編碼器MessageEncoder
public class MessageEncoder extends MessageToByteEncoder<RequestInfoVO> {
private static final String DEFAULT_ENCODE = "utf-8";
private static final int MAGIC_NUMBER = 0x0CAFFEE0;
public MessageEncoder() {
}
@Override
protected void encode(ChannelHandlerContext ctx, RequestInfoVO msg, ByteBuf out) throws Exception {
@SuppressWarnings("resource")
ByteBufOutputStream writer = new ByteBufOutputStream(out);
byte[] body = null;
if (null != msg && null != msg.getBody() && "" != msg.getBody()) {
body = msg.getBody().getBytes(DEFAULT_ENCODE);
}
writer.writeInt(MAGIC_NUMBER);
writer.writeByte(1);
writer.writeByte(msg.getType());
writer.writeInt(msg.getSequence());
if (null == body || 0 == body.length) {
writer.writeInt(0);
} else {
writer.writeInt(body.length);
writer.write(body);
}
}
}
服務端事件處理NettyServerHandler
@Sharable
public class NettyServerHandler extends SimpleChannelInboundHandler<RequestInfoVO> {
private static final Log log = LogFactory.getLog(NettyServerHandler.class);
@Override
protected void channelRead0(ChannelHandlerContext ctx, RequestInfoVO msg) throws Exception {
//
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
}
@Override
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
}
}
客戶端
NettyClientBootstrap連線長連線服務
public class NettyClientBootstrap {
private int port;
private String host;
private SocketChannel socketChannel;
public NettyClientBootstrap(int port, String host) throws Exception {
this.host = host;
this.port = port;
start();
}
private void start() throws Exception {
EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
Bootstrap bootstrap = new Bootstrap();
bootstrap.channel(NioSocketChannel.class);
bootstrap.option(ChannelOption.SO_KEEPALIVE, true);
bootstrap.option(ChannelOption.TCP_NODELAY, true);
bootstrap.group(eventLoopGroup);
bootstrap.remoteAddress(this.host, this.port);
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new MessageDecoder(), new MessageEncoder(), new NettyClientHandler());
}
});
ChannelFuture future = bootstrap.connect(this.host, this.port).sync();
if (future.isSuccess()) {
socketChannel = (SocketChannel) future.channel();
System.out.println("connect server success|");
}
}
public int getPort() {
return this.port;
}
public void setPort(int port) {
this.port = port;
}
public SocketChannel getSocketChannel() {
return socketChannel;
}
public void setSocketChannel(SocketChannel socketChannel) {
this.socketChannel = socketChannel;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
}
初始化客戶端
public static void main(String[] args) throws Exception {
NettyClientBootstrap bootstrap = new NettyClientBootstrap(9999, "127.0.0.1");
int i = 1;
while (true) {
TimeUnit.SECONDS.sleep(2);
RequestInfoVO req = new RequestInfoVO();
req.setSequence(123456);
req.setType((byte) 1);
req.setSequence(0);
req.setBody(String.valueOf((new Date()).getTime()));
bootstrap.getSocketChannel().writeAndFlush(req);
i++;
}
}
根據協議編寫編碼器,解碼器,同服務端編碼器、解碼器
客戶端事件處理
public class NettyClientHandler extends SimpleChannelInboundHandler<RequestInfoVO> {
@Override
protected void messageReceived(ChannelHandlerContext ctx, RequestInfoVO msg) throws Exception {
System.out.println(msg.getBody());
RequestInfoVO req = new RequestInfoVO();
req.setSequence(msg.getSequence());
req.setType(msg.getType());
if (2 == msg.getType()) {
req.setBody("client");
ctx.channel().writeAndFlush(req);
} else if (3 == msg.getType()) {
req.setBody("zpksb");
ctx.channel().writeAndFlush(req);
}
}
}
至此,實現了簡單的客戶端服務端長連線。
相關推薦
Netty實現長連線簡單例子
Netty實現長連線的簡單例子 服務端 NettyServerBootstrap提供長連線服務 public class NettyServerBootstrap { private static final Log log = LogFactory.getLog(Ne
netty 實現長連線,心跳機制,以及重連
實現的功能 心跳機制 and 長連線 and 重連機制 and 應用訊息傳輸: 這裡最關鍵的就是通過netty中的 IdleStateHandler 超時機制來實現心跳和重連 然後通過org.msgpack編碼器來實現跨平臺資料傳輸, 在這實現的功能就是通過Scanner來輸
Java後端實現websocket與微信小程式端連線簡單例子
} 以上是網上的前端及後端的程式碼(原文地址:http://www.cnblogs.com/xdp-gacl/p/5193279.html?utm_source=tuicool&utm_medium=referral),jdk版本要求是在jdk1.7.0以上,tomcat版本也需要在tomcat7.0
基於 django 實現的 webssh 簡單例子
exce attr index tar sum thread 命名 ssh 項目 說明 新建一個 django 程序,本文為 chain。 以下僅為簡單例子,實際應用 可根據自己平臺情況 進行修改。 打開首頁後,需要輸入1,後臺去登錄主機,然後返回登錄結果。 正常項目 可
JavaScript WebSocket實現長連線通訊連線重連
JavaScript-JS依靠WebSoket也可以像其他語言一樣能夠實現通訊程式碼,不過使用的時候需要注意檢查連線斷開的情況。最基本的必須保證IP和埠都可以訪問。 目錄 WebSocket程式碼及測試 呼叫初始化程式碼 通訊示例程式碼 測試效果 WebSocket連線關
使用兩個棧實現佇列,簡單例子
棧, 取值是先進後出 ,後進先出。 那麼怎麼能按照佇列方式(先進先出)存值後取值呢? 看以下程式碼: import java.util.Stack; /** * @Author : JCccc * @Description : * @Point: Keep a good mood
iOS使用GCDSocketManager實現長連線
.h檔案 #import <Foundation/Foundation.h> #import "GCDAsyncSocket.h" @interface GCDSocketManager : NSObject @property(nonatomic,strong) GCDAsyncSocket
Android之通過socket.io實現長連線
在專案開發中,時常有服務端向客戶端主動發起交流的需求,可以整合極光推送,但是如果網路不好的情況下,推送可能會遲遲收不到,這樣就導致了使用者體驗得不到保證。 若改用socket實現長連線的話,速度就快很
網路程式設計知識(5)--用Netty實現的一個簡單的HTTP伺服器
用Netty實現的一個簡單的HTTP伺服器,可以處理靜態檔案,例子中的註釋也比較全。 public class HttpServer { public static void main(String[] args) {
高效 實現長連線保活:手把手教你實現 自適應的心跳保活機制
以下內容轉載自http://blog.csdn.net/carson_ho/article/details/79522975前言當實現具備實時性需求時,我們一般會選擇長連線的通訊方式而在實現長連線方式時,存在很多效能問題,如 長連線保活今天,我將 手把手教大家實現自適應的心跳
使用OkHttp之Websocket實現長連線
最近因為專案中用到了長連線,本來打算使用Socket,無意間發現了Websocket,實現起來很方便。 首先在在build.gradle中新增對Okhttp的支援 compile 'com.squareup.okhttp3:okhttp:3.8.1'
Netty實現客戶端和服務端通信簡單例子
啟動服務 ali tty 過程 等等 服務器初始化 讀寫操作 extends ask Netty是建立在NIO基礎之上,Netty在NIO之上又提供了更高層次的抽象。 在Netty裏面,Accept連接可以使用單獨的線程池去處理,讀寫操作又是另外的線程池來處理。 Accep
Android實現Socket長連線 , OkSocket框架簡單使用
一個Android輕量級Socket通訊框架,既OkHttp後又一力作. 框架開源地址: https://github.com/xuuhaoo/OkSocket OkSocket簡介 Android OkSocket是一款基於阻塞式傳統Socket的一款Socket客戶端整體解決方案.您
netty實現TCP長連線
所用jar包 netty-all-4.1.30.Final.jar 密碼:rzwe NettyConfig.java,存放連線的客戶端 1 import io.netty.channel.group.ChannelGroup; 2 import io.netty.channel.gr
Android推送的核心原理:長連線的簡單實現
實際需求 移動端需要實時的獲取伺服器的資料 解決方案 輪詢方式:應用程式開啟定時的輪詢,不停的向伺服器請求資料。 SMS push:傳送二進位制簡訊到移動終端,來達到通知終端的目的。客戶端攔截這類簡訊,然後採取相應的操作 持久連線方式:應用程式與伺服
Netty實現服務端客戶端長連線通訊及心跳檢測
通過netty實現服務端與客戶端的長連線通訊,及心跳檢測。 基本思路:netty服務端通過一個Map儲存所有連線上來的客戶端SocketChannel,客戶端的Id作為Map的key。每次伺服器端如果要向某個客戶端傳送訊息,只需根據ClientId取出對應的So
(原創)Maven+Spring+CXF+Tomcat7 簡單例子實現webservice
produces per back targe xsd lean listener ans 控制 這個例子需要建三個Maven項目,其中一個為父項目,另外兩個為子項目 首先,建立父項目testParent,選擇quickstart: 輸入項目名稱和模塊名稱,然後創建:
用socket.io實現websocket的一個簡單例子
soc .html www sock 在線 ket log html 簡單例子 http://biyeah.iteye.com/blog/1295196 socket.io的介紹 http://www.cnblogs.com/mazg/p/5467960.html
Netty實現簡單UDP服務器
rec nal req 參考 syn group out equal 文件 本文參考《Netty權威指南》 文件列表: ├── ChineseProverbClientHandler.java ├── ChineseProverbClient.java ├── Chine
使用java實現快速排序的一個簡單例子
fast val rgs 快速 實現 個數 static void sta public static void main(String[] args) { // 測試排序 Random r = new Random(); int arr[] = new