1. 首先创建mvn项目
2. pom中导入jar包
<dependency>
<groupId>io.nettygroupId>
<artifactId>netty-allartifactId>
<version>4.1.24.Finalversion>
dependency>
<dependency>
<groupId>net.sf.json-libgroupId>
<artifactId>json-libartifactId>
<version>2.4version>
<classifier>jdk15classifier>
dependency>
<dependency>
<groupId>net.sf.json-libgroupId>
<artifactId>json-libartifactId>
<version>2.4version>
dependency>
3. 创建客户端
package client;
import io.netty.bootstrap.Bootstrap;
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.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory;
import io.netty.handler.codec.http.websocketx.WebSocketVersion;
import utils.WebSocketResult;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
public class MyClient {
public static void main(String[] args){
EventLoopGroup group=new NioEventLoopGroup();
Bootstrap boot=new Bootstrap();
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
boolean zhen=true;
try{
boot.option(ChannelOption.SO_KEEPALIVE,true)
.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer());
URI websocketURI = new URI("ws://www.baidu.com:8023/user");
HttpHeaders httpHeaders = new DefaultHttpHeaders();
WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.newHandshaker(websocketURI, WebSocketVersion.V13, (String)null, true,httpHeaders);
Channel channel=boot.connect(websocketURI.getHost(),websocketURI.getPort()).sync().channel();
WebSocketClientHandler handler = (WebSocketClientHandler)channel.pipeline().get("hookedHandler");
handler.setHandshaker(handshaker);
handshaker.handshake(channel);
handler.handshakeFuture().sync();
System.out.println("成功!");
Thread.sleep(1000);
try{
while (zhen){
System.out.print("请输入操作:");
String zhi=br.readLine();
TextWebSocketFrame frame = new TextWebSocketFrame(zhi+"\r\n");
channel.writeAndFlush(frame);
}
}catch(Exception e){
br.close();
}
}catch(Exception e){
System.out.println(e.getMessage());
zhen=false;
try{
br.close();
}catch(Exception e){
System.out.println(e.getMessage());
}
}finally {
group.shutdownGracefully();
}
}
}
4.创建协议
package client;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpClientCodec;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.timeout.IdleStateHandler;
import java.util.concurrent.TimeUnit;
public class ChannelInitializer extends io.netty.channel.ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline p = socketChannel.pipeline();
p.addLast(new ChannelHandler[]{
new HttpClientCodec(),new HttpObjectAggregator(1024*1024*10)});
p.addLast(new IdleStateHandler(0,4,0, TimeUnit.SECONDS));
p.addLast(new PingClient());
p.addLast("hookedHandler", new WebSocketClientHandler());
}
}
创建header
package client;
import io.netty.channel.*;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.CharsetUtil;
import utils.JsonStringToClass;
import utils.WebSocketResult;
import java.lang.reflect.Method;
public class WebSocketClientHandler extends SimpleChannelInboundHandler<Object> {
WebSocketClientHandshaker handshaker;
ChannelPromise handshakeFuture;
public void handlerAdded(ChannelHandlerContext ctx) {
this.handshakeFuture = ctx.newPromise();
}
public WebSocketClientHandshaker getHandshaker() {
return handshaker;
}
public void setHandshaker(WebSocketClientHandshaker handshaker) {
this.handshaker = handshaker;
}
public ChannelPromise getHandshakeFuture() {
return handshakeFuture;
}
public void setHandshakeFuture(ChannelPromise handshakeFuture) {
this.handshakeFuture = handshakeFuture;
}
public ChannelFuture handshakeFuture() {
return this.handshakeFuture;
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
Channel ch = ctx.channel();
FullHttpResponse response;
if (!this.handshaker.isHandshakeComplete()) {
try {
response = (FullHttpResponse) msg;
this.handshaker.finishHandshake(ch, response);
this.handshakeFuture.setSuccess();
System.out.println("牵手成功!");
} catch (WebSocketHandshakeException var7) {
FullHttpResponse res = (FullHttpResponse) msg;
String errorMsg = String.format("WebSocket客户端连接失败,状态为:%s", res.status());
this.handshakeFuture.setFailure(new Exception(errorMsg));
}
} else if (msg instanceof FullHttpResponse) {
response = (FullHttpResponse) msg;
throw new IllegalStateException("未预料的错误(getStatus=" + response.status() + ", content=" + response.content().toString(CharsetUtil.UTF_8) + ')');
} else {
WebSocketFrame frame = (WebSocketFrame) msg;
if (frame instanceof TextWebSocketFrame) {
TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;
WebSocketResult webresult= (WebSocketResult) new JsonStringToClass().StringJSONToList(textFrame.text(),WebSocketResult.class);
UseFangfa u=new UseFangfa();
Method method = u.getClass().getMethod(webresult.getAction(),Class.forName("utils.WebSocketResult"),Class.forName("io.netty.channel.Channel"));
method.invoke(u,webresult,ch);
} else if (frame instanceof BinaryWebSocketFrame) {
BinaryWebSocketFrame binFrame = (BinaryWebSocketFrame) frame;
System.out.println("二进制WebSocketFrame");
} else if (frame instanceof PongWebSocketFrame) {
} else if (frame instanceof CloseWebSocketFrame) {
System.out.println("接收关闭贞");
ch.close();
}
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.out.println("发生异常"+cause.getMessage());
ctx.close();
}
}
这里用到的可参考https://blog.csdn.net/weixin_42368893/article/details/99412132
客户端使用ping心跳检测
package client;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelDuplexHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
public class PingClient extends ChannelDuplexHandler {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
IdleStateEvent event = (IdleStateEvent) evt;
if (event.state().equals(IdleState.READER_IDLE)) {
System.out.println("------长期未收到服务器反馈数据------");
} else if (event.state().equals(IdleState.WRITER_IDLE)) {
PingWebSocketFrame p=new PingWebSocketFrame();
ctx.writeAndFlush(p);
} else if (event.state().equals(IdleState.ALL_IDLE)) {
}
}
}
}
反射的方法类
package client;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import utils.WebSocketResult;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class UseFangfa {
public void getdevice(WebSocketResult result, Channel ch){
System.out.println(result.toString());
System.out.println("getdevice方法");
}
public void connect(WebSocketResult result, Channel ch) throws Exception {
if(result.getSuccess()){
System.out.println(result.getContent());
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
}
public void getuserinfo(WebSocketResult result, Channel ch){
System.out.println(result.toString());
System.out.println("获取用户数据");
}
public void getdata(WebSocketResult result){
System.out.println(result.toString());
System.out.println("获取设备运⾏数据");
}
}
最后得到