文档章节

三分钟构建高性能WebSocket服务 | 超优雅的Springboot整合Netty方案

Yeauty
 Yeauty
发布于 09/20 15:16
字数 872
阅读 6137
收藏 1

前言

每当使用SpringBoot进行Weboscket开发时,最容易想到的就是spring-boot-starter-websocket(或spring-websocket)。它可以让我们使用注解,很简单的进行Websocket开发,让我们更多的关注业务逻辑。它底层使用的是Tomcat,且不说把整个Tomcat放进一个WebSocket服务中是否会太重,但在大数据量高并发的场景下,它的表现并不是非常理想。

Netty一款高性能的NIO网络编程框架,在推送量激增时,表现依然出色。(关于性能与表现的讨论,网上很多,这里不过多说明。)很多流行开源项目都在使用Netty,如:Dubbo、Storm、Spark、Elasticsearch、Apache Cassandra等,这得益于Netty的并发高、传输快、封装好等特点。

但是,要在SpringBoot项目中整合Netty来开发WebSocket不是一件舒服的事,这会让你过多的关注非业务逻辑的实现。那么,是否有一款框架,能使得在SpringBoot项目中使用Netty开发WebSocket变得简单,甚至优雅,并且可以从使用spring-boot-starter-websocket开发的项目无缝的迁移过来呢?

netty-websocket-spring-boot-starter

这是个开源的框架。通过它,我们可以像spring-boot-starter-websocket一样使用注解进行开发,只需关注需要的事件(如OnMessage)。并且底层是使用Netty,当需要调参的时候只需要修改配置参数即可,无需过多的关心handler的设置。

快速入门

  • 创建SpringBoot项目(v2.0.0以上)并添加依赖:
	<dependency>
		<groupId>org.yeauty</groupId>
		<artifactId>netty-websocket-spring-boot-starter</artifactId>
		<version>0.6.3</version>
	</dependency>
  • new一个ServerEndpointExporter对象,交给Spring容器,表示要开启WebSocket功能:
@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}
  • 在端点类上加上@ServerEndpoint@Component注解,并在相应的方法上加上@OnOpen@OnClose@OnError@OnMessage注解(不想关注某个事件可不添加对应的注解):
@ServerEndpoint
@Component
public class MyWebSocket {

    @OnOpen
    public void onOpen(Session session, HttpHeaders headers) throws IOException {
        System.out.println("new connection");
    }

    @OnClose
    public void onClose(Session session) throws IOException {
       System.out.println("one connection closed"); 
    }

    @OnError
    public void onError(Session session, Throwable throwable) {
        throwable.printStackTrace();
    }

    @OnMessage
    public void OnMessage(Session session, String message) {
        System.out.println(message);
        session.sendText("Hello Netty!");
    }
}

  • 一个高性能的WebSocket服务端就完成了,直接run起来就可以了。

测试

  • 服务端是写完了,接下来需要测试一下,看看效果
  • 首先,新建一个html文件,把页面撸出来
<!DOCTYPE html>
<html lang="en">
<body>
<div id="msg"></div>
<input type="text" id="text">
<input type="submit" value="send" onclick="send()">
</body>
<script>
    var msg = document.getElementById("msg");
    var wsServer = 'ws://127.0.0.1:80';
    var websocket = new WebSocket(wsServer);
    //监听连接打开
    websocket.onopen = function (evt) {
        msg.innerHTML = "The connection is open";
    };

    //监听服务器数据推送
    websocket.onmessage = function (evt) {
        msg.innerHTML += "<br>" + evt.data;
    };

    //监听连接关闭
    websocket.onclose = function (evt) {
        alert("连接关闭");
    };

    function send() {
        var text = document.getElementById("text").value
        websocket.send(text);
    }
</script>
</html>
  • 页面撸完,直接用Chrome打开上面html文件即可连上你的WebSocket服务。

总结

这个框架是基于Netty的,所以直接使用Netty优化时的理念即可。如:堆外内存的0拷贝、接收及发送缓冲区的调整、高低写水位的调整等。

生产环境的项目在充分调优后,Netty甚至能比Tomcat高效20倍。(当然,这是特定的场景下)

框架详细文档:https://github.com/YeautyYE/netty-websocket-spring-boot-starter

© 著作权归作者所有

共有 人打赏支持
Yeauty
粉丝 4
博文 2
码字总数 1532
作品 0
深圳
加载中

评论(11)

Yeauty
Yeauty

引用来自“红薯”的评论

仓库放码云吧,我们推荐一下:)

引用来自“Yeauty”的评论

不好意思,现在才回你。
代码已经放到码云:https://gitee.com/Yeauty/netty-websocket-spring-boot-starter
谢谢了

引用来自“Ralph王”的评论

跑不通,运行的时候提示
java.lang.RuntimeException: pojoMethodMapping.paramWithoutAnnotation
  at org.yeauty.pojo.PojoMethodMapping.getPathParams(PojoMethodMapping.java:281) ~[netty-websocket-spring-boot-starter-0.6.2.jar:na]
  at org.yeauty.pojo.PojoMethodMapping.(PojoMethodMapping.java:165) ~[netty-websocket-spring-boot-starter-0.6.2.jar:na]
  at org.yeauty.standard.ServerEndpointExporter.registerEndpoint(ServerEndpointExporter.java:76) ~[netty-websocket-spring-boot-starter-0.6.2.jar:na]
你的session是不是导错包了
Ralph王
Ralph王

引用来自“红薯”的评论

仓库放码云吧,我们推荐一下:)

引用来自“Yeauty”的评论

不好意思,现在才回你。
代码已经放到码云:https://gitee.com/Yeauty/netty-websocket-spring-boot-starter
谢谢了
跑不通,运行的时候提示
java.lang.RuntimeException: pojoMethodMapping.paramWithoutAnnotation
  at org.yeauty.pojo.PojoMethodMapping.getPathParams(PojoMethodMapping.java:281) ~[netty-websocket-spring-boot-starter-0.6.2.jar:na]
  at org.yeauty.pojo.PojoMethodMapping.(PojoMethodMapping.java:165) ~[netty-websocket-spring-boot-starter-0.6.2.jar:na]
  at org.yeauty.standard.ServerEndpointExporter.registerEndpoint(ServerEndpointExporter.java:76) ~[netty-websocket-spring-boot-starter-0.6.2.jar:na]
Yeauty
Yeauty

引用来自“红薯”的评论

仓库放码云吧,我们推荐一下:)
不好意思,现在才回你。
代码已经放到码云:https://gitee.com/Yeauty/netty-websocket-spring-boot-starter
谢谢了
罗格林
罗格林
不错. 不过比起 #ActFramework# 写 WebSocket 应用还是稍显复杂: https://my.oschina.net/greenlaw110/blog/1807429
_loop
_loop
只能说,这个做法没有什么卵用。用websocket是为了异步处理。这个框架只能同步,没什么意义。
Eriloan
Eriloan
这标题,没谁了。
理工男海哥
理工男海哥
只能说,文章没有任何意义,不知道为什么小编会推荐?感觉小编是高校新招实习生。另一个是和 #Jboot# 比,差远了...
art_youth
art_youth
感觉和PHP实现差不多:http://manual.eqphp.com/index.html#28
啪啪啪的_指针
啪啪啪的_指针
高并发是个伪命题
银杏果果
银杏果果
完全不用考虑断网重连吗?意义何在呢?
spring boot整合Websocket笔记

特别说明:自学笔记 使用websocket有两种方式: 使用sockjs, 使用h5的标准。 使用Html5标准自然更方便简单,所以记录的是配合h5的使用方法。 1、pom.xml中添加如下: 核心是@ServerEndpoint...

jackcooper2015
2017/12/28
0
0
springboot整合websocket(1)

一、背景   我们都知道http协议只能浏览器单方面向服务器发起请求获得响应,服务器不能主动向浏览器推送消息。想要实现浏览器的主动推送有两种主流实现方式: 轮询:缺点很多,但是实现简单...

烦嚣的人
08/01
0
0
Spring Boot 之Websocket 编程笔记

有时候会用到向前端页推送消息的情况,这时候就会用到WebSocket 编程了, 1.在pom.xml 中添加如下配置 1.1核心是@ServerEndpoint这个注解。这个注解是Javaee标准里的注解,tomcat7以上已经对...

kuchawyz
09/20
0
0
WebSoket初探并于SpringBoot整合

版权声明:本文版权归Jitwxs所有,欢迎转载,但未经作者同意必须保留原文链接。 https://blog.csdn.net/yuanlaijike/article/details/83002143 一、WebSocket 1.1 HTTP与WebSocket WebSocket...

Jitwxs
10/10
0
0
SpringBoot 使用WebSocket

WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。 本文档主要介绍了如何在SpringBoot中使用WebSocket。 通过...

阿刚ABC
2017/11/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Ubuntu18.04下载安装Google图解法

首先Ctrl + Alt + T打开终端,或者可以在在搜索框搜索终端。 (1)sudo wget http://www.linuxidc.com/files/repo/google-chrome.list -P /etc/apt/sources.list.d/ ,(将下载源加入到系统的...

AI_SKI
11分钟前
0
0
spring could采坑 eureka开启验证后无法连接注册中心

com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server at com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClie......

君千殇520
11分钟前
0
0
支付宝小程序下单支付接口:40004 ACQ.INVALID_PARAMETER

下面是支付宝下单接口 https://docs.open.alipay.com/api_1/alipay.trade.create/ 如果按官方文档的说明,并没有解释清楚buyer_id什么时候要传,只是说:特殊可选,啥叫特殊可选?!在调小程...

swingcoder
20分钟前
0
0
【Java】广州三本秋招经历

前言 只有光头才能变强 离上次发文章已经快两个月时间了,最近一直忙着秋招的事。今天是2018年10月22日,对于互联网行业来说,秋招就基本结束了。我这边的流程也走完了(不再笔试/面试了),所...

Java3y
22分钟前
1
0
在idea中启动多个SpringBoot项目

https://blog.csdn.net/forezp/article/details/76408139

灯下草虫鸣_
23分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部