依赖

  1. <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
  2. <dependency>
  3. <groupId>commons-io</groupId>
  4. <artifactId>commons-io</artifactId>
  5. <version>2.4</version>
  6. </dependency>

也用了

  1. <dependency>
  2. <groupId>org.projectlombok</groupId>
  3. <artifactId>lombok</artifactId>
  4. <version>1.18.20</version>
  5. </dependency>

WebsocketNettyServerBootstrap.java

  1. import io.netty.bootstrap.ServerBootstrap;
  2. import io.netty.channel.*;
  3. import io.netty.channel.nio.NioEventLoopGroup;
  4. import io.netty.channel.socket.SocketChannel;
  5. import io.netty.channel.socket.nio.NioServerSocketChannel;
  6. import io.netty.handler.codec.http.HttpObjectAggregator;
  7. import io.netty.handler.codec.http.HttpServerCodec;
  8. import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
  9. import io.netty.handler.stream.ChunkedWriteHandler;
  10.  
  11. /**
  12. * 服务启动类
  13. */
  14. public class WebsocketNettyServerBootstrap {
  15.  
  16. public static void main(String[] args) {
  17. EventLoopGroup bossGroup = new NioEventLoopGroup();
  18. EventLoopGroup workerGroup = new NioEventLoopGroup();
  19. try {
  20. //创建服务器端的启动对象,配置参数
  21. ServerBootstrap bootstrap = new ServerBootstrap();
  22. //设置两个线程组
  23. bootstrap.group(bossGroup, workerGroup)
  24. //使用NioServerSocketChannel 作为服务器的通道实现
  25. .channel(NioServerSocketChannel.class)
  26. //设置线程队列得到连接个数
  27. .option(ChannelOption.SO_BACKLOG, 128)
  28. //设置保持活动连接状态
  29. .childOption(ChannelOption.SO_KEEPALIVE, true)
  30. //给workerGroup 的 EventLoop 对应的管道设置处理器
  31. .childHandler(new ChannelInitializer<SocketChannel>() {
  32.  
  33. @Override
  34. protected void initChannel(SocketChannel ch) throws Exception {
  35. ChannelPipeline pipeline = ch.pipeline();
  36. /**
  37. * 因为基于http协议,使用http的编解码器
  38. */
  39. pipeline.addLast(new HttpServerCodec());
  40.  
  41. /**
  42. * 是以块方式写,添加 ChunkedWriteHandler 处理器
  43. */
  44. pipeline.addLast(new ChunkedWriteHandler());
  45. /**
  46. * http数据传输过程是分段的,HttpObjectAggregator,就是可以将多段聚合
  47. * 当浏览器发送大量数据时,就会发出多次http请求
  48. */
  49. pipeline.addLast(new HttpObjectAggregator(8192));
  50. /**
  51. * 对于websocket数据是以 帧 形式传递
  52. * 浏览器请求时 ws://localhost:7000/hello 其中 hello会与下面的对应
  53. * WebSocketServerProtocolHandler 核心功能是将http协议升级为ws协议,保持长链接
  54. */
  55. pipeline.addLast(new WebSocketServerProtocolHandler("/hello"));
  56.  
  57. //自定义handler
  58. pipeline.addLast(new TextWebsocketFrameHandler());
  59. }
  60. });
  61.  
  62. //启动服务器并绑定一个端口并且同步生成一个 ChannelFuture 对象
  63. ChannelFuture cf = bootstrap.bind(7000).sync();
  64. if (cf.isSuccess()) {
  65. System.out.println("websocket server start---------------");
  66. }
  67.  
  68. //对关闭通道进行监听
  69. cf.channel().closeFuture().sync();
  70. } catch (Exception e) {
  71. e.printStackTrace();
  72. } finally {
  73. //发送异常关闭
  74. bossGroup.shutdownGracefully();
  75. workerGroup.shutdownGracefully();
  76.  
  77. }
  78. }
  79. }

TextWebsocketFrameHandler.java

  1. import io.netty.channel.ChannelHandlerContext;
  2. import io.netty.channel.SimpleChannelInboundHandler;
  3. import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
  4. import lombok.extern.slf4j.Slf4j;
  5.  
  6. /**
  7. * TextWebSocketFrame 表示一个文本帧
  8. */
  9. @Slf4j
  10. public class TextWebsocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
  11. @Override
  12. protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
  13. log.info(">>>>>>>>>>>服务端收到消息:{}", msg.text());
  14.  
  15. /**
  16. * 回复消息
  17. */
  18. ctx.writeAndFlush(new TextWebSocketFrame("服务器收到了,并返回:"+msg.text()));
  19. }
  20.  
  21. /**
  22. * 当web客户端连接后,触发方法
  23. * @param ctx
  24. * @throws Exception
  25. */
  26. @Override
  27. public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
  28. /**
  29. * 这个ID是唯一的
  30. */
  31. log.info(">>>>>>>>>>>> channelId:{} 连接",ctx.channel().id().asLongText());
  32.  
  33. /**
  34. * 这个ID不是唯一的
  35. */
  36. log.info(">>>>>>>>>>>> channelId:{} 连接",ctx.channel().id().asShortText());
  37. }
  38.  
  39. @Override
  40. public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
  41. log.info(">>>>>>>>>>>>> channelId:{} 关闭了",ctx.channel().id().asLongText());
  42. }
  43.  
  44. @Override
  45. public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
  46. log.error(">>>>>>>>发送异常:{}",cause.getMessage());
  47. ctx.close();
  48. }
  49. }

JAVA使用netty建立websocket连接的更多相关文章

  1. 结合实际需求,在webapi内利用WebSocket建立单向的消息推送平台,让A页面和服务端建立WebSocket连接,让其他页面可以及时给A页面推送消息

    1.需求示意图 2.需求描述 原本是为了给做unity3d客户端开发的同事提供不定时的消息推送,比如商城购买道具后服务端将道具信息推送给客户端. 本篇文章简化理解,用“相关部门开展活动,向全市人民征集 ...

  2. 使用wireshark抓包分析浏览器无法建立WebSocket连接的问题(server为Alchemy WebSockets组件)

    工作时使用了Websocket技术,在使用的过程中发现,浏览器(Chrome)升级后可能会导致Websocket不可用,更换浏览器后可以正常使用. 近日偶尔一次在本地调试,发现使用相同版本的Chrom ...

  3. HTML5 WebSocket与C# 建立Socket连接

    一.WebSocket 概述 WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务 ...

  4. 教你正确地利用Netty建立连接池

    一.问题描述 Netty是最近非常流行的高性能异步通讯框架,相对于Java原生的NIO接口,Netty封装后的异步通讯机制要简单很多. 但是小K最近发现并不是所有开发人员在使用的过程中都了解其内部实现 ...

  5. Caused by: java.io.IOException: 您的主机中的软件中止了一个已建立的连接。

    异常详情 2017-07-16 10:55:26,218 ERROR [500.jsp] - java.io.IOException: 你的主机中的软件中止了一个已建立的连接. org.apache. ...

  6. Caused by: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。

    org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接. at org ...

  7. org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接。

    org.apache.catalina.connector.ClientAbortException: java.io.IOException: 你的主机中的软件中止了一个已建立的连接. at org ...

  8. java.io.IOException: 您的主机中的软件中止了一个已建立的连接解决办法

    问题现象和http://hi.baidu.com/cara_cloud/item/193a3ee327546d395a2d64be描述的一样,就是在eclipse的console栏中一直显示java. ...

  9. java.io.IOException: 你的主机中的软件中止了一个已建立的连接。

    1.异常表现:我在jsp文件中有一个<form>表单,里面有一个<button>保存事件按钮.<button  onclick="addOrUPdate()&q ...

随机推荐

  1. 洛谷 P4663 - [BalticOI 2008]魔法石(dp)

    题面传送门 A:我该是有多无聊来写这种题的题解啊 B:大概是因为这题题解区里没有题解所以我来写一篇了,说明我有高尚的济世情怀(大雾 跑题了跑题了 首先看到字典序第 \(i\) 小小可以自然地想到按位决 ...

  2. CF1437G Death DBMS

    题面传送门. 题意简述:给出 \(n\) 个字符串 \(s_i\),每个 \(s_i\) 初始权值为 \(0\).\(q\) 次操作:修改 \(s_i\) 的权值:查询给出字符串 \(q\) 能匹配的 ...

  3. 记一次VS2010和VS2015自定义颜色的过程

    首先,是遇到的问题: 一天,使用VS2010看新项目代码时候,发现选中某个变量后,其它位置高亮显示的变量颜色太淡,不利于阅读代码,如下图.所以想修改这个颜色. 后来网上找了一遍,可以这样设置:工具-- ...

  4. C++ and OO Num. Comp. Sci. Eng. - Part 2.

    本文参考自<C++ and Object-Oriented Numeric Computing for Scientists and Engineers>. 1. Basic Types ...

  5. R包对植物进行GO,KEGG注释

    1.安装,加载所用到到R包 用BiocManager安装,可同时加载依赖包 source("https://bioconductor.org/biocLite.R") BiocMa ...

  6. Django向数据库批量插入数据

    # 如何向数据库一次性插入多条数据 # 方法一:效率极低,不推荐使用 for i in range(1000): models.Book.objects.create(title=f'第{i}本书') ...

  7. tcp可靠传输的机制有哪些(面试必看

    一.综述 1.确认和重传:接收方收到报文就会确认,发送方发送一段时间后没有收到确认就重传. 2.数据校验 3.数据合理分片和排序: UDP:IP数据报大于1500字节,大于MTU.这个时候发送方IP层 ...

  8. 详解getchar()函数与缓冲区

    1.首先,我们看一下这段代码: 它的简单意思就是从键盘读入一个字符,然后输出到屏幕.理所当然,我们输入1,输出就是1,输入2,输出就是2. 那么我们如果输出的是12呢? 它的输出是1. 这里我们先简单 ...

  9. Vue相关,Vue JSX

    JSX简介 JSX是一种Javascript的语法扩展,JSX = Javascript + XML,即在Javascript里面写XML,因为JSX的这个特性,所以他即具备了Javascript的灵 ...

  10. Linux学习 - 网络命令

    一.write 1 功能 给指定在线用户发信息,以Ctrl + D保存结束 2 语法 write  <用户名>  [信息] 二.wall(write all) 1 功能 给所有在线用户发送 ...