当前位置: 首页 > news >正文

淘宝网站建设协议附子seo教程

淘宝网站建设协议,附子seo教程,seo工资水平,长沙多迪php网站开发培训学校服务器与浏览器之间实现通信#xff0c;一般都是由浏览器发起http请求#xff0c;服务端对http请求进行响应#xff0c;要实现服务端主动向浏览器推送数据#xff0c;一般采用的方案都是websocket主动推送#xff0c;或者前端实现轮询方式拉取数据#xff0c;轮询方式多少…服务器与浏览器之间实现通信一般都是由浏览器发起http请求服务端对http请求进行响应要实现服务端主动向浏览器推送数据一般采用的方案都是websocket主动推送或者前端实现轮询方式拉取数据轮询方式多少有点浪费资源并且消息推送也不够及时。目前很多系统都是采用websocket协议进行主动推送数据给前端。在springboot中是支持websocket协议的但是这里想讲的是通过netty实现websocket通信。 首先需要引入netty的依赖包 dependencygroupIdio.netty/groupIdartifactIdnetty-all/artifactIdversion4.1.90.Final/version /dependency这里面已经包含了websocket协议相关的编解码。下面介绍两种方案使用websocket协议一种是内置的处理ws消息另外一种是自己实现相关消息的解析和处理。 首先介绍第一种使用这种方案只需要用户自己定义一个handler实现消息的接收和业务处理把处理结果返回给浏览器就可以了大致代码逻辑如下 定义handler用于处理ws消息 import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;/*** 用户自定义websocket消息处理handler** Author xingo* Date 2023/11/21*/ public class UserWebsocketInHandler extends SimpleChannelInboundHandlerTextWebSocketFrame {Overrideprotected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) throws Exception {String text frame.text();System.out.println(Thread.currentThread().getName() | text);ctx.writeAndFlush(new TextWebSocketFrame(server send message : text));} }服务端引入websocket相关handler和自定义handler import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.stream.ChunkedWriteHandler; import io.netty.handler.timeout.IdleStateEvent; import io.netty.handler.timeout.IdleStateHandler;import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger;/*** websocket服务端** Author xingo* Date 2023/11/21*/ public class NettyWebsocketServer implements Runnable {/*** 服务端IP地址*/private String ip;/*** 服务端端口号*/private int port;public NettyWebsocketServer(String ip, int port) {this.ip ip;this.port port;}Overridepublic void run() {// 指定boss线程数主要负责接收连接请求一般设置为1就可以final EventLoopGroup boss new NioEventLoopGroup(1, new ThreadFactory() {private AtomicInteger index new AtomicInteger(0);Overridepublic Thread newThread(Runnable r) {return new Thread(r, String.format(NioBoss_%d, this.index.incrementAndGet()));}});// 指定worker线程数主要负责处理连接就绪的连接一般设置为CPU的核心数final int totalThread 12;final EventLoopGroup worker new NioEventLoopGroup(totalThread, new ThreadFactory() {private AtomicInteger index new AtomicInteger(0);Overridepublic Thread newThread(Runnable r) {return new Thread(r, String.format(NioSelector_%d_%d, totalThread, this.index.incrementAndGet()));}});// 指定任务处理线程数主要负责读取数据和处理响应一般该值设置的比较大与业务相对应final int jobThreads 1024;final EventLoopGroup job new DefaultEventLoopGroup(jobThreads, new ThreadFactory() {private AtomicInteger index new AtomicInteger(0);Overridepublic Thread newThread(Runnable r) {return new Thread(r, String.format(NioJob_%d_%d, jobThreads, this.index.incrementAndGet()));}});// 日志处理handler类定义上面有Sharable表示线程安全可以将对象定义在外面使用final LoggingHandler LOGGING_HANDLER new LoggingHandler();// 指定服务端bootstrapServerBootstrap server new ServerBootstrap();server.group(boss, worker)// 指定通道类型.channel(NioServerSocketChannel.class)// 指定全连接队列大小windows下默认是200linux/mac下默认是128.option(ChannelOption.SO_BACKLOG, 2048)// 维持链接的活跃清除死链接.childOption(ChannelOption.SO_KEEPALIVE, true)// 关闭延迟发送.childOption(ChannelOption.TCP_NODELAY, true)// 添加handler处理链.childHandler(new ChannelInitializerNioSocketChannel() {Overrideprotected void initChannel(NioSocketChannel channel) throws Exception {ChannelPipeline pipeline channel.pipeline();// 日志处理pipeline.addLast(LOGGING_HANDLER);// 心跳检测读超时时间、写超时时间、全部超时时间单位是秒0表示不处理pipeline.addLast(new IdleStateHandler(30,0,0, TimeUnit.SECONDS));pipeline.addLast(new ChannelDuplexHandler() {Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {IdleStateEvent event (IdleStateEvent) evt;System.out.println(心跳事件 : event.state());super.userEventTriggered(ctx, evt);}});// 处理http请求的编解码器pipeline.addLast(job, httpServerCodec, new HttpServerCodec());pipeline.addLast(job, chunkedWriteHandler, new ChunkedWriteHandler());pipeline.addLast(job, httpObjectAggregator, new HttpObjectAggregator(65536));// 处理websocket的编解码器pipeline.addLast(job, webSocketServerProtocolHandler, new WebSocketServerProtocolHandler(/, WebSocket, true, 655360));// 自定义处理器pipeline.addLast(job, userInHandler, new UserWebsocketInHandler());}});try {// 服务端绑定对外服务地址ChannelFuture future server.bind(ip, port).sync();System.out.println(netty server start ok.);// 等待服务关闭关闭后释放相关资源future.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();} finally {boss.shutdownGracefully();worker.shutdownGracefully();job.shutdownGracefully();}}public static void main(String[] args) {new Thread(new NettyWebsocketServer(127.0.0.1, 8899)).start();} }以上就实现了websocket服务端客户端连接到服务端实现双向通信。 另外一种实现方式是自己定义一个handler用于ws协议数据的解析和处理这样协议的整个处理过程对于用户来说很清楚明白下面是实现的逻辑代码 首先定义一个handler用于ws协议解析和处理 import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.*; import io.netty.handler.codec.http.websocketx.*; import io.netty.util.AttributeKey; import io.netty.util.CharsetUtil; import lombok.extern.slf4j.Slf4j;/***** Author xingo* Date 2023/11/21*/ Slf4j public class WebsocketServerHandler extends SimpleChannelInboundHandlerObject {private WebSocketServerHandshaker handshaker;public WebsocketServerHandler() {}private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame msg) {if (msg instanceof CloseWebSocketFrame) {handshaker.close(ctx.channel(), (CloseWebSocketFrame) msg.retain());return;}if (msg instanceof PingWebSocketFrame) {log.info(websocket ping message);ctx.channel().write(new PingWebSocketFrame(msg.content().retain()));} else if (msg instanceof TextWebSocketFrame) {// websocket消息解压成字符串让下一个handler处理String text ((TextWebSocketFrame) msg).text();log.info(请求数据|{}, text);// 如果不调用这个方法后面的handler就获取不到数据ctx.fireChannelRead(text);} else {log.error(不支持的消息格式);throw new UnsupportedOperationException(不支持的消息格式);}}private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest msg) {if (!msg.decoderResult().isSuccess()|| (!websocket.equalsIgnoreCase(msg.headers().get(HttpHeaderNames.UPGRADE)))) {sendHttpResponse(ctx, msg, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));return;}WebSocketServerHandshakerFactory wsShakerFactory new WebSocketServerHandshakerFactory(ws:// msg.headers().get(HttpHeaderNames.HOST), null, false);handshaker wsShakerFactory.newHandshaker(msg);if (handshaker null) {WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());} else {// 建立websocket连接握手handshaker.handshake(ctx.channel(), msg);ctx.channel().attr(AttributeKey.valueOf(add)).set(Boolean.TRUE);}}private void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest msg, DefaultFullHttpResponse response) {if (response.status().code() ! HttpResponseStatus.OK.code()) {ByteBuf buf Unpooled.copiedBuffer(response.status().toString(), CharsetUtil.UTF_8);response.content().writeBytes(buf);buf.release();}ChannelFuture cf ctx.channel().writeAndFlush(response);if (!HttpUtil.isKeepAlive(msg) || response.status().code() ! HttpResponseStatus.OK.code()) {cf.addListener(ChannelFutureListener.CLOSE);}}Overridepublic void channelReadComplete(ChannelHandlerContext ctx) throws Exception {ctx.flush();}Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {ctx.channel().attr(AttributeKey.valueOf(add)).set(Boolean.FALSE);ctx.close();}Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {ctx.channel().attr(AttributeKey.valueOf(add)).set(Boolean.FALSE);ctx.close();}Overrideprotected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {if (msg instanceof FullHttpRequest) {handleHttpRequest(ctx, (FullHttpRequest) msg);} else if (msg instanceof WebSocketFrame) {handleWebSocketFrame(ctx, (WebSocketFrame) msg);}} }上面对ws协议进行了处理处理后的数据直接解析成字符串给后续的handler。 定义两个handler用于数据处理和封装 import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;/*** 入站处理器获取请求数据完成业务处理推送消息给浏览器* * Author xingo* Date 2023/11/21*/ public class UserWebsocketInHandler extends SimpleChannelInboundHandlerString {Overrideprotected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {System.out.println(Thread.currentThread().getName() | msg);// ctx.writeAndFlush(new TextWebSocketFrame(server send message : msg));ctx.writeAndFlush(server send message : msg);} }import io.netty.channel.*; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;/*** 出站处理器判断数据是否需要进行封装* * Author xingo* Date 2023/11/21*/ public class UserWebsocketOutHandler extends ChannelOutboundHandlerAdapter {Overridepublic void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {if(msg instanceof String) {ctx.write(new TextWebSocketFrame((String) msg), promise);} else {super.write(ctx, msg, promise);}} }websocket服务端代码 import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.stream.ChunkedWriteHandler; import io.netty.handler.timeout.IdleStateEvent; import io.netty.handler.timeout.IdleStateHandler;import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger;/*** websocket服务端** Author xingo* Date 2023/11/21*/ public class NettyWebsocketServer implements Runnable {/*** 服务端IP地址*/private String ip;/*** 服务端端口号*/private int port;public NettyWebsocketServer(String ip, int port) {this.ip ip;this.port port;}Overridepublic void run() {// 指定boss线程数主要负责接收连接请求一般设置为1就可以final EventLoopGroup boss new NioEventLoopGroup(1, new ThreadFactory() {private AtomicInteger index new AtomicInteger(0);Overridepublic Thread newThread(Runnable r) {return new Thread(r, String.format(NioBoss_%d, this.index.incrementAndGet()));}});// 指定worker线程数主要负责处理连接就绪的连接一般设置为CPU的核心数final int totalThread 12;final EventLoopGroup worker new NioEventLoopGroup(totalThread, new ThreadFactory() {private AtomicInteger index new AtomicInteger(0);Overridepublic Thread newThread(Runnable r) {return new Thread(r, String.format(NioSelector_%d_%d, totalThread, this.index.incrementAndGet()));}});// 指定任务处理线程数主要负责读取数据和处理响应一般该值设置的比较大与业务相对应final int jobThreads 1024;final EventLoopGroup job new DefaultEventLoopGroup(jobThreads, new ThreadFactory() {private AtomicInteger index new AtomicInteger(0);Overridepublic Thread newThread(Runnable r) {return new Thread(r, String.format(NioJob_%d_%d, jobThreads, this.index.incrementAndGet()));}});// 日志处理handler类定义上面有Sharable表示线程安全可以将对象定义在外面使用final LoggingHandler LOGGING_HANDLER new LoggingHandler();// 指定服务端bootstrapServerBootstrap server new ServerBootstrap();server.group(boss, worker)// 指定通道类型.channel(NioServerSocketChannel.class)// 指定全连接队列大小windows下默认是200linux/mac下默认是128.option(ChannelOption.SO_BACKLOG, 2048)// 维持链接的活跃清除死链接.childOption(ChannelOption.SO_KEEPALIVE, true)// 关闭延迟发送.childOption(ChannelOption.TCP_NODELAY, true)// 添加handler处理链.childHandler(new ChannelInitializerNioSocketChannel() {Overrideprotected void initChannel(NioSocketChannel channel) throws Exception {ChannelPipeline pipeline channel.pipeline();// 日志处理pipeline.addLast(LOGGING_HANDLER);// 心跳检测读超时时间、写超时时间、全部超时时间单位是秒0表示不处理pipeline.addLast(new IdleStateHandler(30,0,0, TimeUnit.SECONDS));pipeline.addLast(new ChannelDuplexHandler() {Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {IdleStateEvent event (IdleStateEvent) evt;System.out.println(心跳事件 : event.state());super.userEventTriggered(ctx, evt);}});// 处理http请求的编解码器pipeline.addLast(job, httpServerCodec, new HttpServerCodec());pipeline.addLast(job, chunkedWriteHandler, new ChunkedWriteHandler());pipeline.addLast(job, httpObjectAggregator, new HttpObjectAggregator(65536));// 处理websocket的编解码器pipeline.addLast(job, websocketHandler, new WebsocketServerHandler());// 自定义处理器pipeline.addLast(job, userOutHandler, new UserWebsocketOutHandler());pipeline.addLast(job, userInHandler, new UserWebsocketInHandler());}});try {// 服务端绑定对外服务地址ChannelFuture future server.bind(ip, port).sync();System.out.println(netty server start ok.);// 等待服务关闭关闭后释放相关资源future.channel().closeFuture().sync();} catch (InterruptedException e) {e.printStackTrace();} finally {boss.shutdownGracefully();worker.shutdownGracefully();job.shutdownGracefully();}}public static void main(String[] args) {new Thread(new NettyWebsocketServer(127.0.0.1, 8899)).start();} }上面这种方式同样实现了websocket通信并且可以清楚的知道连接创建和数据交互的整个过程。
http://www.sczhlp.com/news/178684/

相关文章:

  • 温州网站快速排名景区协会官方网站建设
  • 网站的访问速度seo 培训教程
  • html5国外网站模板html源码下载网站开发环境搭建章节教材书
  • 企业网站建设备案都需要什么怎么删除wordpress主题
  • 网页设计师联盟网站wordpress批量给图片加水印
  • 扫黄除恶网站构造结构怎么做wordpress调用多媒体
  • 拖拽式制作网站网站建设网站公司的序
  • 网站后台管理生成器织梦发布文章wordpress
  • 济南网站建设 济南货梯wordpress导航栏特效插件
  • 大视觉网站建设东莞网站优化有哪些
  • 可以做微商的网站佛山网站优化排名推广
  • 信息中心完成网站建设深圳搜索排名优化
  • 网站备案号如何获得免费网站建站排名
  • 用别人的电影网站做公众号数学网站怎么做的
  • 建设银行洛阳市分行网站html网页完整代码作业简单
  • 素材
  • Hyper-v 安装 Android9
  • test8 - post
  • 泉州市住房和乡村建设网站招聘网站怎么做市场
  • 网站加搜索框ui网站界面设计模板
  • 做网站窗体属性栏设置文字居中正中路桥建设发展有限公司网站
  • 制作网站建设规划书的结构为网站建设思维
  • 智联招聘网站建设情况企业网站 需求
  • 播州区住房城乡建设路的网站商品行情软件下载
  • 网站建设费钱吗已备案域名买卖
  • 石家庄网站seo优化公司模块网站制作
  • 网站在公司做有什么要求吗长沙网站制作哪里好
  • 广州网站seo地址谷德建筑设计网
  • 海口自助建站现在那个网站做推广效果会好点
  • 成都网站建设网站制作公司网页制作主题