文档章节

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

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

前言

每当使用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
Spring Boot 之Websocket 编程笔记

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

kuchawyz
09/20
0
0
springboot整合websocket(1)

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

烦嚣的人
08/01
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

没有更多内容

加载失败,请刷新页面

加载更多

MicroStation Developer Shell

REG ADD HKLM\SOFTWARE\Microsoft\VisualStudio\8.0\Setup\VS /v ProductDir /t REG_SZ /d "C:\Program Files (x86)\Microsoft Visual Studio 8\VC\" /reg:32 CALL "C:\Program Files (x86)\......

oready
11分钟前
1
0
CURL常用命令

下载单个文件,默认将输出打印到标准输出中(STDOUT)中 curl http://www.centos.org 通过-o/-O选项保存下载的文件到指定的文件中: -o:将文件保存为命令行中指定的文件名的文件中 -O:使用U...

SuShine
15分钟前
1
0
docker搞个wordpress

1.先把wordpress的镜像下载下来 docker pull wordpress 2.下载mysql docker pull mysql:lastest 3.启动mysql docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:t......

无极之岚
27分钟前
2
0
【宇润日常疯测-005】PHP 中的 clone 和 new 性能比较

clone和new本不应该放在一起比较,它们的作用是不同的。但可能有一些场景下,可以用clone也可以用new,那么这时候我们选哪个呢? 我编写了两个测试,第一个是声明一个空类,第二个是带构造方...

宇润
28分钟前
2
1
点击按钮弹出类似IOS 底部 dialog

implementation 'com.baoyz.actionsheet:library:1.1.7' 然后设置按钮点击监听,,调用下列代码即可 ActionSheet.createBuilder(this, getSupportFragmentManager()) ......

lanyu96
31分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部