Comments (5)
客户端定时发送 ping操作帧
即可
from netty-websocket-spring-boot-starter.
0.8.0版本 手写一个Java客户端 进入ping 没收到服务端消息.
from netty-websocket-spring-boot-starter.
0.8.0版本 手写一个Java客户端 进入ping 没收到服务端消息.
你的代码发一下
from netty-websocket-spring-boot-starter.
用的你们0.8.0版本代码作为服务端,客户端自己写的。
请问SimpleChannelInboundHandler接口如何支持不同类型,如ByteBuf等.
以下为客户端三个类参考Code: CustomHeartbeatHandler、ClientHandler、Client;
package com.crc.crcloud.steam.deploy.netty;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleStateEvent;
/**
-
@CreateAuthor: biao.sun
-
@Createdate: 2019-10-18 09:40
*/
public abstract class CustomHeartbeatHandler extends SimpleChannelInboundHandler {
public static final byte PING_MSG = 1;
public static final byte PONG_MSG = 2;
public static final byte CUSTOM_MSG = 3;
protected String name;
private int heartbeatCount = 0;public CustomHeartbeatHandler(String name) {
this.name = name;
}@OverRide
protected void channelRead0(ChannelHandlerContext context, ByteBuf byteBuf) throws Exception {
if (byteBuf.getByte(4) == PING_MSG) {
sendPongMsg(context);
} else if (byteBuf.getByte(4) == PONG_MSG){
System.out.println(name + " get pong msg from " + context.channel().remoteAddress());
} else {
handleData(context, byteBuf);
}
}protected void sendPingMsg(ChannelHandlerContext context) {
ByteBuf buf = context.alloc().buffer(5);
buf.writeInt(5);
buf.writeByte(PING_MSG);
context.writeAndFlush(buf);
heartbeatCount++;
System.out.println(name + " sent ping msg to " + context.channel().remoteAddress() + ", count: " + heartbeatCount);
}private void sendPongMsg(ChannelHandlerContext context) {
ByteBuf buf = context.alloc().buffer(5);
buf.writeInt(5);
buf.writeByte(PONG_MSG);
context.channel().writeAndFlush(buf);
heartbeatCount++;
System.out.println(name + " sent pong msg to " + context.channel().remoteAddress() + ", count: " + heartbeatCount);
}protected abstract void handleData(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf);
@OverRide
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
// IdleStateHandler 所产生的 IdleStateEvent 的处理逻辑.
if (evt instanceof IdleStateEvent) {
IdleStateEvent e = (IdleStateEvent) evt;
switch (e.state()) {
case READER_IDLE:
handleReaderIdle(ctx);
break;
case WRITER_IDLE:
handleWriterIdle(ctx);
break;
case ALL_IDLE:
handleAllIdle(ctx);
break;
default:
break;
}
}
}@OverRide
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.err.println("---" + ctx.channel().remoteAddress() + " is active---");
}@OverRide
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.err.println("---" + ctx.channel().remoteAddress() + " is inactive---");
}protected void handleReaderIdle(ChannelHandlerContext ctx) {
System.err.println("---READER_IDLE---");
}protected void handleWriterIdle(ChannelHandlerContext ctx) {
System.err.println("---WRITER_IDLE---");
}protected void handleAllIdle(ChannelHandlerContext ctx) {
System.err.println("---ALL_IDLE---");
}
}
package com.crc.crcloud.steam.deploy.netty.client;
import com.crc.crcloud.steam.deploy.netty.CustomHeartbeatHandler;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
/**
-
@CreateAuthor: biao.sun
-
@Createdate: 2019-10-18 09:47
*/
public class ClientHandler extends CustomHeartbeatHandler {public ClientHandler() {
super("client");
}@OverRide
protected void handleData(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) {
byte[] data = new byte[byteBuf.readableBytes() - 5];
byteBuf.skipBytes(5);
byteBuf.readBytes(data);
String content = new String(data);
System.out.println(name + " get content: " + content);
}@OverRide
protected void handleAllIdle(ChannelHandlerContext ctx) {
super.handleAllIdle(ctx);
sendPingMsg(ctx);
}
}
package com.crc.crcloud.steam.deploy.netty.client;
import com.crc.crcloud.steam.deploy.netty.CustomHeartbeatHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.timeout.IdleStateHandler;
import java.util.Random;
/**
-
@CreateAuthor: biao.sun
-
@Createdate: 2019-10-17 14:35
*/
public class Client {public static void main(String[] args) {
NioEventLoopGroup workGroup = new NioEventLoopGroup(4);
Random random = new Random(System.currentTimeMillis());
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap
.group(workGroup)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer() {
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline p = socketChannel.pipeline();
p.addLast(new IdleStateHandler(0, 0, 5));
p.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 4, -4, 0));
p.addLast(new ClientHandler());
p.addLast(new WebSocketServerProtocolHandler("/webSocket/agent/log", null, true, 65536 * 10));
}
});Channel ch = bootstrap.remoteAddress("10.54.8.35", 18499).connect().sync().channel(); for (int i = 0; i < 10; i++) { String content = "client msg " + i; ByteBuf buf = ch.alloc().buffer(); buf.writeInt(5 + content.getBytes().length); buf.writeByte(CustomHeartbeatHandler.CUSTOM_MSG); buf.writeBytes(content.getBytes()); ch.writeAndFlush(buf); Thread.sleep(random.nextInt(10000)); } } catch (Exception e) { throw new RuntimeException(e); } finally { workGroup.shutdownGracefully(); }
}
}
from netty-websocket-spring-boot-starter.
建议直接使用Netty的PingWebSocketFrame
from netty-websocket-spring-boot-starter.
Related Issues (20)
- 系统消息,如果通过广播形势发送到所有session或指定/ws/{arg}对应的session? HOT 2
- springboot3.0 无法正常使用
- 支持注册到nacos上吗 HOT 1
- BeforeHandshake关闭session后,nginx转发http响应的502 HOT 2
- 想问下服务器如何判断客户端掉线,然后通知他的好友 HOT 2
- writerIdleTimeSeconds配置使用${引用nacos配置},不能做到动态刷新 HOT 1
- 整合RocketMq后异常日志不全 HOT 2
- netty默认的Channel的通道id太长了,目前框架上支持这个id自定义吗? HOT 1
- 客户端断网后服务端不知道客户端断开了 HOT 1
- 请问如何处理数据库存储的客户端连接状态,假如单节点部署,重启过程中客户端离线,数据库的状态如何改变呢,有什么策略可以主动ping客户端吗 HOT 1
- 想问一下0.12版本客户端访问问题 HOT 1
- 使用@ServerEndpoint修饰但不用@Component时,其它Bean注入该Bean时会报 bean could not be found 异常 HOT 2
- 客户端在线,服务端离线 HOT 1
- 是否支持socketjs+stomp? HOT 1
- 连接报错,发送消息也报错。。。看内容吧。。。 HOT 3
- 能否支持自定义全局异常处理? HOT 1
- 能否进一步优化反射方法性能 HOT 1
- 0.12.0使用的netty版本和文档不一致 HOT 2
- 支持TCP吗?
- pojoClazz 不是单例的吗
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from netty-websocket-spring-boot-starter.