基于netty访问WebSocket(java的websocket客户端)(访问远程ws协议)
生活随笔
收集整理的這篇文章主要介紹了
基于netty访问WebSocket(java的websocket客户端)(访问远程ws协议)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
1. 首先創(chuàng)建mvn項(xiàng)目
2. pom中導(dǎo)入jar包
<dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.24.Final</version></dependency><dependency><groupId>net.sf.json-lib</groupId><artifactId>json-lib</artifactId><version>2.4</version><classifier>jdk15</classifier></dependency><dependency><groupId>net.sf.json-lib</groupId><artifactId>json-lib</artifactId><version>2.4</version></dependency>3. 創(chuàng)建客戶(hù)端
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;//客戶(hù)端 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());//引用自己的協(xié)議//ws協(xié)議類(lèi)型 URI websocketURI = new URI("ws://www.baidu.com:8023/user");HttpHeaders httpHeaders = new DefaultHttpHeaders();//進(jìn)行握手WebSocketClientHandshaker handshaker = WebSocketClientHandshakerFactory.newHandshaker(websocketURI, WebSocketVersion.V13, (String)null, true,httpHeaders);//需要協(xié)議的host和portChannel 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("成功!");//讓線(xiàn)程睡眠1秒,以免數(shù)據(jù)收回慢Thread.sleep(1000);try{while (zhen){System.out.print("請(qǐng)輸入操作:");String zhi=br.readLine();//發(fā)送textwebsocketframe格式的請(qǐng)求//TextWebSocketFrame 可以任意轉(zhuǎn)換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 {//優(yōu)雅關(guān)閉group.shutdownGracefully();}} }4.創(chuàng)建協(xié)議
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> {@Overrideprotected 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()); //心跳 機(jī)制p.addLast("hookedHandler", new WebSocketClientHandler());} }創(chuàng)建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; //這里的泛型我用的是object,也可以用TextWebSocketFrame 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;}@Overrideprotected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {Channel ch = ctx.channel();FullHttpResponse response;//判斷接收的請(qǐng)求是否是牽手if (!this.handshaker.isHandshakeComplete()) {try {response = (FullHttpResponse) msg;//握手協(xié)議返回,設(shè)置結(jié)束握手this.handshaker.finishHandshake(ch, response);//設(shè)置成功this.handshakeFuture.setSuccess();System.out.println("牽手成功!");} catch (WebSocketHandshakeException var7) {FullHttpResponse res = (FullHttpResponse) msg;String errorMsg = String.format("WebSocket客戶(hù)端連接失敗,狀態(tài)為:%s", res.status());this.handshakeFuture.setFailure(new Exception(errorMsg));}} else if (msg instanceof FullHttpResponse) {response = (FullHttpResponse) msg;//可以吧字符碼轉(zhuǎn)為指定類(lèi)型//this.listener.onFail(response.status().code(), response.content().toString(CharsetUtil.UTF_8));throw new IllegalStateException("未預(yù)料的錯(cuò)誤(getStatus=" + response.status() + ", content=" + response.content().toString(CharsetUtil.UTF_8) + ')');} else {//如果不是牽手WebSocketFrame frame = (WebSocketFrame) msg;if (frame instanceof TextWebSocketFrame) {TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;//這里我用了一個(gè)返回自己的格式的類(lèi)型和一個(gè)json字符串轉(zhuǎn)為對(duì)象的方法WebSocketResult webresult= (WebSocketResult) new JsonStringToClass().StringJSONToList(textFrame.text(),WebSocketResult.class);UseFangfa u=new UseFangfa();//如果反射方法有多個(gè)參數(shù)可以在逗號(hào)后面現(xiàn)指定多種類(lèi)型,然后在反射方法中傳入多個(gè)參數(shù)Method method = u.getClass().getMethod(webresult.getAction(),Class.forName("utils.WebSocketResult"),Class.forName("io.netty.channel.Channel"));//反射方法method.invoke(u,webresult,ch); // System.out.println("收到消息:"+textFrame.text());} else if (frame instanceof BinaryWebSocketFrame) {BinaryWebSocketFrame binFrame = (BinaryWebSocketFrame) frame;System.out.println("二進(jìn)制WebSocketFrame");} else if (frame instanceof PongWebSocketFrame) {//返回心跳監(jiān)測(cè)//System.out.println("WebSocket客戶(hù)端接收到pong");} else if (frame instanceof CloseWebSocketFrame) {System.out.println("接收關(guān)閉貞");//this.listener.onClose(((CloseWebSocketFrame)frame).statusCode(), ((CloseWebSocketFrame)frame).reasonText());ch.close();}}}/*發(fā)生異常直接關(guān)閉客戶(hù)端*/@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {System.out.println("發(fā)生異常"+cause.getMessage());ctx.close();} }這里用到的可參考https://blog.csdn.net/weixin_42368893/article/details/99412132
客戶(hù)端使用ping心跳檢測(cè)
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 {@Overridepublic 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("------長(zhǎng)期未收到服務(wù)器反饋數(shù)據(jù)------");//根據(jù)具體的情況 在這里也可以重新連接} else if (event.state().equals(IdleState.WRITER_IDLE)) {//System.out.println("------長(zhǎng)期未向服務(wù)器發(fā)送數(shù)據(jù) 發(fā)送心跳------");//System.out.println("------發(fā)送心跳包------ping\r\n"); // ctx.writeAndFlush(getSendByteBuf("ping"));PingWebSocketFrame p=new PingWebSocketFrame();ctx.writeAndFlush(p);} else if (event.state().equals(IdleState.ALL_IDLE)) {}}} }反射的方法類(lèi)
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("登錄成功");//下面可以進(jìn)行ch里發(fā)送消息的操作}else{System.out.println("登錄失敗");}}public void getuserinfo(WebSocketResult result, Channel ch){System.out.println(result.toString());System.out.println("獲取用戶(hù)數(shù)據(jù)");}public void getdata(WebSocketResult result){System.out.println(result.toString());System.out.println("獲取設(shè)備運(yùn)?數(shù)據(jù)");} }最后得到
總結(jié)
以上是生活随笔為你收集整理的基于netty访问WebSocket(java的websocket客户端)(访问远程ws协议)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 洛图科技:第三季度中国 VR / AR
- 下一篇: layui的空行格